summary refs log tree commit diff
path: root/src/systemd
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-03-26 23:25:23 +0100
committerMichael Biebl <biebl@debian.org>2019-03-26 23:25:23 +0100
commit9a6dcbf895f9da01768e64b73cec88c16157d91e (patch)
treea359958930d731e9f1b59344642e10754419fe84 /src/systemd
parent964ae8cc391520440cf5aa13e2b9cc34850ea6c2 (diff)
New upstream version 1.16.0 upstream/1.16.0
Diffstat (limited to 'src/systemd')
-rw-r--r--src/systemd/meson.build117
-rw-r--r--src/systemd/nm-sd-utils-core.c (renamed from src/systemd/nm-sd-utils.c)25
-rw-r--r--src/systemd/nm-sd-utils-core.h (renamed from src/systemd/nm-sd-utils.h)14
-rw-r--r--src/systemd/nm-sd.c6
-rw-r--r--src/systemd/sd-adapt-core/condition.h (renamed from src/systemd/sd-adapt/condition.h)0
-rw-r--r--src/systemd/sd-adapt-core/conf-parser.h (renamed from src/systemd/sd-adapt/conf-parser.h)0
-rw-r--r--src/systemd/sd-adapt-core/device-util.h (renamed from src/systemd/sd-adapt/architecture.h)0
-rw-r--r--src/systemd/sd-adapt-core/khash.h (renamed from src/systemd/sd-adapt/khash.h)0
-rw-r--r--src/systemd/sd-adapt-core/nm-sd-adapt-core.c (renamed from src/systemd/sd-adapt/nm-sd-adapt.c)2
-rw-r--r--src/systemd/sd-adapt-core/nm-sd-adapt-core.h101
-rw-r--r--src/systemd/sd-adapt-core/sd-daemon.h (renamed from src/systemd/sd-adapt/sd-daemon.h)0
-rw-r--r--src/systemd/sd-adapt-core/sd-device.h (renamed from src/systemd/sd-adapt/sd-device.h)0
-rw-r--r--src/systemd/sd-adapt-core/stat-util.h (renamed from src/systemd/sd-adapt/stat-util.h)0
-rw-r--r--src/systemd/sd-adapt/btrfs-util.h3
-rw-r--r--src/systemd/sd-adapt/build.h3
-rw-r--r--src/systemd/sd-adapt/cgroup-util.h3
-rw-r--r--src/systemd/sd-adapt/copy.h3
-rw-r--r--src/systemd/sd-adapt/def.h3
-rw-r--r--src/systemd/sd-adapt/device-nodes.h3
-rw-r--r--src/systemd/sd-adapt/dirent-util.h3
-rw-r--r--src/systemd/sd-adapt/errno-list.h3
-rw-r--r--src/systemd/sd-adapt/format-util.h3
-rw-r--r--src/systemd/sd-adapt/glob-util.h3
-rw-r--r--src/systemd/sd-adapt/gunicode.h3
-rw-r--r--src/systemd/sd-adapt/ioprio.h3
-rw-r--r--src/systemd/sd-adapt/locale-util.h3
-rw-r--r--src/systemd/sd-adapt/memfd-util.h3
-rw-r--r--src/systemd/sd-adapt/missing.h3
-rw-r--r--src/systemd/sd-adapt/mkdir.h3
-rw-r--r--src/systemd/sd-adapt/nm-sd-adapt.h191
-rw-r--r--src/systemd/sd-adapt/procfs-util.h3
-rw-r--r--src/systemd/sd-adapt/raw-clone.h3
-rw-r--r--src/systemd/sd-adapt/terminal-util.h3
-rw-r--r--src/systemd/sd-adapt/unaligned.h3
-rw-r--r--src/systemd/sd-adapt/user-util.h3
-rw-r--r--src/systemd/sd-adapt/virt.h3
-rw-r--r--src/systemd/src/basic/alloc-util.c83
-rw-r--r--src/systemd/src/basic/alloc-util.h130
-rw-r--r--src/systemd/src/basic/async.h7
-rw-r--r--src/systemd/src/basic/env-util.c791
-rw-r--r--src/systemd/src/basic/env-util.h50
-rw-r--r--src/systemd/src/basic/escape.c509
-rw-r--r--src/systemd/src/basic/escape.h55
-rw-r--r--src/systemd/src/basic/ether-addr-util.c119
-rw-r--r--src/systemd/src/basic/ether-addr-util.h28
-rw-r--r--src/systemd/src/basic/extract-word.c289
-rw-r--r--src/systemd/src/basic/extract-word.h17
-rw-r--r--src/systemd/src/basic/fd-util.c959
-rw-r--r--src/systemd/src/basic/fd-util.h110
-rw-r--r--src/systemd/src/basic/fileio.c1671
-rw-r--r--src/systemd/src/basic/fileio.h96
-rw-r--r--src/systemd/src/basic/fs-util.c1256
-rw-r--r--src/systemd/src/basic/fs-util.h109
-rw-r--r--src/systemd/src/basic/hash-funcs.c120
-rw-r--r--src/systemd/src/basic/hash-funcs.h45
-rw-r--r--src/systemd/src/basic/hashmap.c1988
-rw-r--r--src/systemd/src/basic/hashmap.h393
-rw-r--r--src/systemd/src/basic/hexdecoct.c821
-rw-r--r--src/systemd/src/basic/hexdecoct.h38
-rw-r--r--src/systemd/src/basic/hostname-util.c295
-rw-r--r--src/systemd/src/basic/hostname-util.h27
-rw-r--r--src/systemd/src/basic/in-addr-util.c602
-rw-r--r--src/systemd/src/basic/in-addr-util.h60
-rw-r--r--src/systemd/src/basic/io-util.c256
-rw-r--r--src/systemd/src/basic/io-util.h73
-rw-r--r--src/systemd/src/basic/list.h169
-rw-r--r--src/systemd/src/basic/log.h326
-rw-r--r--src/systemd/src/basic/macro.h476
-rw-r--r--src/systemd/src/basic/mempool.c87
-rw-r--r--src/systemd/src/basic/mempool.h27
-rw-r--r--src/systemd/src/basic/parse-util.c749
-rw-r--r--src/systemd/src/basic/parse-util.h119
-rw-r--r--src/systemd/src/basic/path-util.c1060
-rw-r--r--src/systemd/src/basic/path-util.h175
-rw-r--r--src/systemd/src/basic/prioq.c303
-rw-r--r--src/systemd/src/basic/prioq.h25
-rw-r--r--src/systemd/src/basic/process-util.c1505
-rw-r--r--src/systemd/src/basic/process-util.h200
-rw-r--r--src/systemd/src/basic/random-util.c220
-rw-r--r--src/systemd/src/basic/random-util.h25
-rw-r--r--src/systemd/src/basic/refcnt.h16
-rw-r--r--src/systemd/src/basic/set.h132
-rw-r--r--src/systemd/src/basic/signal-util.h43
-rw-r--r--src/systemd/src/basic/siphash24.h53
-rw-r--r--src/systemd/src/basic/socket-util.c1254
-rw-r--r--src/systemd/src/basic/socket-util.h187
-rw-r--r--src/systemd/src/basic/sparse-endian.h93
-rw-r--r--src/systemd/src/basic/stat-util.c272
-rw-r--r--src/systemd/src/basic/stat-util.h61
-rw-r--r--src/systemd/src/basic/stdio-util.h60
-rw-r--r--src/systemd/src/basic/string-table.c19
-rw-r--r--src/systemd/src/basic/string-table.h112
-rw-r--r--src/systemd/src/basic/string-util.c1079
-rw-r--r--src/systemd/src/basic/string-util.h230
-rw-r--r--src/systemd/src/basic/strv.c888
-rw-r--r--src/systemd/src/basic/strv.h177
-rw-r--r--src/systemd/src/basic/time-util.c1503
-rw-r--r--src/systemd/src/basic/time-util.h183
-rw-r--r--src/systemd/src/basic/umask-util.h28
-rw-r--r--src/systemd/src/basic/utf8.c453
-rw-r--r--src/systemd/src/basic/utf8.h48
-rw-r--r--src/systemd/src/basic/util.c609
-rw-r--r--src/systemd/src/basic/util.h209
-rw-r--r--src/systemd/src/libsystemd-network/arp-util.c2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.c59
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-lease-internal.h4
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-network.c42
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-option.c3
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-packet.c85
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-internal.h6
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-lease-internal.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-network.c17
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-option.c103
-rw-r--r--src/systemd/src/libsystemd-network/lldp-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/lldp-neighbor.c45
-rw-r--r--src/systemd/src/libsystemd-network/lldp-neighbor.h3
-rw-r--r--src/systemd/src/libsystemd-network/lldp-network.c3
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c99
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.h12
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c312
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c121
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c375
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-lease.c59
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4acd.c62
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4ll.c26
-rw-r--r--src/systemd/src/libsystemd-network/sd-lldp.c113
-rw-r--r--src/systemd/src/libsystemd/sd-event/event-source.h206
-rw-r--r--src/systemd/src/libsystemd/sd-event/event-util.c100
-rw-r--r--src/systemd/src/libsystemd/sd-event/event-util.h13
-rw-r--r--src/systemd/src/libsystemd/sd-event/sd-event.c504
-rw-r--r--src/systemd/src/libsystemd/sd-id128/id128-util.c14
-rw-r--r--src/systemd/src/libsystemd/sd-id128/id128-util.h4
-rw-r--r--src/systemd/src/libsystemd/sd-id128/sd-id128.c47
-rw-r--r--src/systemd/src/shared/dns-domain.c115
-rw-r--r--src/systemd/src/shared/dns-domain.h33
-rw-r--r--src/systemd/src/systemd/_sd-common.h18
-rw-r--r--src/systemd/src/systemd/sd-dhcp-client.h3
-rw-r--r--src/systemd/src/systemd/sd-dhcp-lease.h3
-rw-r--r--src/systemd/src/systemd/sd-dhcp6-client.h10
-rw-r--r--src/systemd/src/systemd/sd-event.h7
-rw-r--r--src/systemd/src/systemd/sd-id128.h17
-rw-r--r--src/systemd/src/systemd/sd-lldp.h30
-rw-r--r--src/systemd/src/systemd/sd-ndisc.h6
144 files changed, 1493 insertions, 25889 deletions
diff --git a/src/systemd/meson.build b/src/systemd/meson.build
index 1bf1ea41..9dea4fb5 100644
--- a/src/systemd/meson.build
+++ b/src/systemd/meson.build
@@ -1,73 +1,46 @@
-sources = files(
-  'sd-adapt/nm-sd-adapt.c',
-  'src/basic/alloc-util.c',
-  'src/basic/escape.c',
-  'src/basic/env-util.c',
-  'src/basic/ether-addr-util.c',
-  'src/basic/extract-word.c',
-  'src/basic/fd-util.c',
-  'src/basic/fileio.c',
-  'src/basic/fs-util.c',
-  'src/basic/hash-funcs.c',
-  'src/basic/hashmap.c',
-  'src/basic/hexdecoct.c',
-  'src/basic/hostname-util.c',
-  'src/basic/in-addr-util.c',
-  'src/basic/io-util.c',
-  'src/basic/mempool.c',
-  'src/basic/parse-util.c',
-  'src/basic/path-util.c',
-  'src/basic/prioq.c',
-  'src/basic/process-util.c',
-  'src/basic/random-util.c',
-  'src/basic/socket-util.c',
-  'src/basic/stat-util.c',
-  'src/basic/string-table.c',
-  'src/basic/string-util.c',
-  'src/basic/strv.c',
-  'src/basic/time-util.c',
-  'src/basic/utf8.c',
-  'src/basic/util.c',
-  'src/libsystemd-network/arp-util.c',
-  'src/libsystemd-network/dhcp-identifier.c',
-  'src/libsystemd-network/dhcp-network.c',
-  'src/libsystemd-network/dhcp-option.c',
-  'src/libsystemd-network/dhcp-packet.c',
-  'src/libsystemd-network/dhcp6-network.c',
-  'src/libsystemd-network/dhcp6-option.c',
-  'src/libsystemd-network/lldp-neighbor.c',
-  'src/libsystemd-network/lldp-network.c',
-  'src/libsystemd-network/network-internal.c',
-  'src/libsystemd-network/sd-dhcp-client.c',
-  'src/libsystemd-network/sd-dhcp-lease.c',
-  'src/libsystemd-network/sd-dhcp6-client.c',
-  'src/libsystemd-network/sd-dhcp6-lease.c',
-  'src/libsystemd-network/sd-ipv4acd.c',
-  'src/libsystemd-network/sd-ipv4ll.c',
-  'src/libsystemd-network/sd-lldp.c',
-  'src/libsystemd/sd-event/sd-event.c',
-  'src/libsystemd/sd-id128/id128-util.c',
-  'src/libsystemd/sd-id128/sd-id128.c',
-  'src/shared/dns-domain.c',
-  'nm-sd.c',
-  'nm-sd-utils.c',
-)
-
-incs = [
-  src_inc,
-  include_directories(
-    'sd-adapt',
-    'src/basic',
-    'src/libsystemd-network',
-    'src/shared',
-    'src/systemd'
-  )
-]
-
-libsystemd_nm = static_library(
-  'systemd-nm',
-  sources: sources,
-  include_directories: incs,
-  dependencies: nm_core_dep,
-  c_args: '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_SYSTEMD'
+libnm_systemd_core = static_library(
+  'nm-systemd-core',
+  sources: files(
+    'sd-adapt-core/nm-sd-adapt-core.c',
+    'src/libsystemd-network/arp-util.c',
+    'src/libsystemd-network/dhcp-identifier.c',
+    'src/libsystemd-network/dhcp-network.c',
+    'src/libsystemd-network/dhcp-option.c',
+    'src/libsystemd-network/dhcp-packet.c',
+    'src/libsystemd-network/dhcp6-network.c',
+    'src/libsystemd-network/dhcp6-option.c',
+    'src/libsystemd-network/lldp-neighbor.c',
+    'src/libsystemd-network/lldp-network.c',
+    'src/libsystemd-network/network-internal.c',
+    'src/libsystemd-network/sd-dhcp-client.c',
+    'src/libsystemd-network/sd-dhcp-lease.c',
+    'src/libsystemd-network/sd-dhcp6-client.c',
+    'src/libsystemd-network/sd-dhcp6-lease.c',
+    'src/libsystemd-network/sd-ipv4acd.c',
+    'src/libsystemd-network/sd-ipv4ll.c',
+    'src/libsystemd-network/sd-lldp.c',
+    'src/libsystemd/sd-event/event-util.c',
+    'src/libsystemd/sd-event/sd-event.c',
+    'src/libsystemd/sd-id128/id128-util.c',
+    'src/libsystemd/sd-id128/sd-id128.c',
+    'src/shared/dns-domain.c',
+    'nm-sd.c',
+    'nm-sd-utils-core.c',
+  ),
+  include_directories: [
+    src_inc,
+    include_directories(
+      'sd-adapt-core',
+      'src/libsystemd-network',
+      'src/libsystemd/sd-event',
+      'src/shared',
+      'src/systemd',
+    )
+  ],
+  dependencies: [
+    nm_core_dep,
+  ],
+  c_args: [
+    '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_SYSTEMD',
+  ],
 )
diff --git a/src/systemd/nm-sd-utils.c b/src/systemd/nm-sd-utils-core.c
index c6c4c123..42560789 100644
--- a/src/systemd/nm-sd-utils.c
+++ b/src/systemd/nm-sd-utils-core.c
@@ -18,37 +18,16 @@
 
 #include "nm-default.h"
 
-#include "nm-sd-utils.h"
+#include "nm-sd-utils-core.h"
 
 #include "nm-core-internal.h"
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include "path-util.h"
 #include "sd-id128.h"
 
 /*****************************************************************************/
 
-gboolean
-nm_sd_utils_path_equal (const char *a, const char *b)
-{
-	return path_equal (a, b);
-}
-
-char *
-nm_sd_utils_path_simplify (char *path, gboolean kill_dots)
-{
-	return path_simplify (path, kill_dots);
-}
-
-const char *
-nm_sd_utils_path_startswith (const char *path, const char *prefix)
-{
-	return path_startswith (path, prefix);
-}
-
-/*****************************************************************************/
-
 NMUuid *
 nm_sd_utils_id128_get_machine (NMUuid *out_uuid)
 {
diff --git a/src/systemd/nm-sd-utils.h b/src/systemd/nm-sd-utils-core.h
index 0af514eb..a7b092b3 100644
--- a/src/systemd/nm-sd-utils.h
+++ b/src/systemd/nm-sd-utils-core.h
@@ -16,16 +16,8 @@
  * Copyright (C) 2018 Red Hat, Inc.
  */
 
-#ifndef __NM_SD_UTILS_H__
-#define __NM_SD_UTILS_H__
-
-/*****************************************************************************/
-
-gboolean nm_sd_utils_path_equal (const char *a, const char *b);
-
-char *nm_sd_utils_path_simplify (char *path, gboolean kill_dots);
-
-const char *nm_sd_utils_path_startswith (const char *path, const char *prefix);
+#ifndef __NM_SD_UTILS_CORE_H__
+#define __NM_SD_UTILS_CORE_H__
 
 /*****************************************************************************/
 
@@ -35,4 +27,4 @@ struct _NMUuid *nm_sd_utils_id128_get_machine (struct _NMUuid *out_uuid);
 
 /*****************************************************************************/
 
-#endif /* __NM_SD_UTILS_H__ */
+#endif /* __NM_SD_UTILS_CORE_H__ */
diff --git a/src/systemd/nm-sd.c b/src/systemd/nm-sd.c
index cbef91d1..4009c617 100644
--- a/src/systemd/nm-sd.c
+++ b/src/systemd/nm-sd.c
@@ -133,9 +133,13 @@ nm_sd_event_attach_default (void)
 
 /*****************************************************************************/
 
+const bool mempool_use_allowed = true;
+
+/*****************************************************************************/
+
 /* ensure that defines in nm-sd.h correspond to the internal defines. */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 #include "dhcp-lease-internal.h"
 
 /*****************************************************************************/
diff --git a/src/systemd/sd-adapt/condition.h b/src/systemd/sd-adapt-core/condition.h
index d3a6812a..d3a6812a 100644
--- a/src/systemd/sd-adapt/condition.h
+++ b/src/systemd/sd-adapt-core/condition.h
diff --git a/src/systemd/sd-adapt/conf-parser.h b/src/systemd/sd-adapt-core/conf-parser.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/conf-parser.h
+++ b/src/systemd/sd-adapt-core/conf-parser.h
diff --git a/src/systemd/sd-adapt/architecture.h b/src/systemd/sd-adapt-core/device-util.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/architecture.h
+++ b/src/systemd/sd-adapt-core/device-util.h
diff --git a/src/systemd/sd-adapt/khash.h b/src/systemd/sd-adapt-core/khash.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/khash.h
+++ b/src/systemd/sd-adapt-core/khash.h
diff --git a/src/systemd/sd-adapt/nm-sd-adapt.c b/src/systemd/sd-adapt-core/nm-sd-adapt-core.c
index 4e308276..d7ed687e 100644
--- a/src/systemd/sd-adapt/nm-sd-adapt.c
+++ b/src/systemd/sd-adapt-core/nm-sd-adapt-core.c
@@ -18,7 +18,7 @@
 
 #include "nm-default.h"
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include "fd-util.h"
 
diff --git a/src/systemd/sd-adapt-core/nm-sd-adapt-core.h b/src/systemd/sd-adapt-core/nm-sd-adapt-core.h
new file mode 100644
index 00000000..8c07c53a
--- /dev/null
+++ b/src/systemd/sd-adapt-core/nm-sd-adapt-core.h
@@ -0,0 +1,101 @@
+/* This program 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 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 - 2018 Red Hat, Inc.
+ */
+
+#ifndef __NM_SD_ADAPT_CORE_H__
+#define __NM_SD_ADAPT_CORE_H__
+
+#include "nm-default.h"
+
+#include <stdbool.h>
+#include <sys/resource.h>
+#include <time.h>
+
+#include "systemd/sd-adapt-shared/nm-sd-adapt-shared.h"
+
+#ifndef HAVE_SYS_AUXV_H
+#define HAVE_SYS_AUXV_H 0
+#endif
+
+/*****************************************************************************
+ * The remainder of the header is only enabled when building the systemd code
+ * itself.
+ *****************************************************************************/
+
+#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD
+
+#include <netinet/in.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <elf.h>
+#ifdef HAVE_SYS_AUXV_H
+#include <sys/auxv.h>
+#endif
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/ioctl.h>
+
+#include <net/if_arp.h>
+
+/* Missing in Linux 3.2.0, in Ubuntu 12.04 */
+#ifndef BPF_XOR
+#define BPF_XOR 0xa0
+#endif
+
+#ifndef ETHERTYPE_LLDP
+#define ETHERTYPE_LLDP 0x88cc
+#endif
+
+#ifndef HAVE_SECURE_GETENV
+#  ifdef HAVE___SECURE_GETENV
+#    define secure_getenv __secure_getenv
+#  else
+#    error neither secure_getenv nor __secure_getenv is available
+#  endif
+#endif
+
+/*****************************************************************************/
+
+static inline int
+sd_notify (int unset_environment, const char *state)
+{
+	return 0;
+}
+
+/* Can't include both net/if.h and linux/if.h; so have to define this here */
+#ifndef IF_NAMESIZE
+#define IF_NAMESIZE 16
+#endif
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ IF_NAMESIZE
+#endif
+
+#ifndef MAX_HANDLE_SZ
+#define MAX_HANDLE_SZ 128
+#endif
+
+#include "sd-id128.h"
+#include "sparse-endian.h"
+#include "async.h"
+#include "util.h"
+
+#endif /* (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD */
+
+#endif /* __NM_SD_ADAPT_CORE_H__ */
+
diff --git a/src/systemd/sd-adapt/sd-daemon.h b/src/systemd/sd-adapt-core/sd-daemon.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/sd-daemon.h
+++ b/src/systemd/sd-adapt-core/sd-daemon.h
diff --git a/src/systemd/sd-adapt/sd-device.h b/src/systemd/sd-adapt-core/sd-device.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/sd-device.h
+++ b/src/systemd/sd-adapt-core/sd-device.h
diff --git a/src/systemd/sd-adapt/stat-util.h b/src/systemd/sd-adapt-core/stat-util.h
index 637892c2..637892c2 100644
--- a/src/systemd/sd-adapt/stat-util.h
+++ b/src/systemd/sd-adapt-core/stat-util.h
diff --git a/src/systemd/sd-adapt/btrfs-util.h b/src/systemd/sd-adapt/btrfs-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/btrfs-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/build.h b/src/systemd/sd-adapt/build.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/build.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/cgroup-util.h b/src/systemd/sd-adapt/cgroup-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/cgroup-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/copy.h b/src/systemd/sd-adapt/copy.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/copy.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/def.h b/src/systemd/sd-adapt/def.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/def.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/device-nodes.h b/src/systemd/sd-adapt/device-nodes.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/device-nodes.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/dirent-util.h b/src/systemd/sd-adapt/dirent-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/dirent-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/errno-list.h b/src/systemd/sd-adapt/errno-list.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/errno-list.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/format-util.h b/src/systemd/sd-adapt/format-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/format-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/glob-util.h b/src/systemd/sd-adapt/glob-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/glob-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/gunicode.h b/src/systemd/sd-adapt/gunicode.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/gunicode.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/ioprio.h b/src/systemd/sd-adapt/ioprio.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/ioprio.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/locale-util.h b/src/systemd/sd-adapt/locale-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/locale-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/memfd-util.h b/src/systemd/sd-adapt/memfd-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/memfd-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/missing.h b/src/systemd/sd-adapt/missing.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/missing.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/mkdir.h b/src/systemd/sd-adapt/mkdir.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/mkdir.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/nm-sd-adapt.h b/src/systemd/sd-adapt/nm-sd-adapt.h
deleted file mode 100644
index e163eeda..00000000
--- a/src/systemd/sd-adapt/nm-sd-adapt.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2014 - 2015 Red Hat, Inc.
- */
-
-#ifndef NM_SD_ADAPT_H
-#define NM_SD_ADAPT_H
-
-#include "nm-default.h"
-
-#include <stdbool.h>
-#include <syslog.h>
-#include <sys/resource.h>
-#include <time.h>
-
-#if defined(HAVE_DECL_REALLOCARRAY) && HAVE_DECL_REALLOCARRAY == 1
-#define HAVE_REALLOCARRAY 1
-#else
-#define HAVE_REALLOCARRAY 0
-#endif
-
-#if defined(HAVE_DECL_EXPLICIT_BZERO) && HAVE_DECL_EXPLICIT_BZERO == 1
-#define HAVE_EXPLICIT_BZERO 1
-#else
-#define HAVE_EXPLICIT_BZERO 0
-#endif
-
-#define ENABLE_DEBUG_HASHMAP 0
-
-#ifndef HAVE_SYS_AUXV_H
-#define HAVE_SYS_AUXV_H 0
-#endif
-
-/*****************************************************************************/
-
-static inline NMLogLevel
-_slog_level_to_nm (int slevel)
-{
-    switch (LOG_PRI (slevel)) {
-    case LOG_DEBUG:   return LOGL_DEBUG;
-	case LOG_WARNING: return LOGL_WARN;
-	case LOG_CRIT:
-	case LOG_ERR:     return LOGL_ERR;
-	case LOG_INFO:
-	case LOG_NOTICE:
-	default:          return LOGL_INFO;
-	}
-}
-
-static inline int
-_nm_log_get_max_level_realm (void)
-{
-	/* inline function, to avoid coverity warning about constant expression. */
-	return LOG_DEBUG;
-}
-#define log_get_max_level_realm(realm) _nm_log_get_max_level_realm ()
-
-#define log_internal_realm(level, error, file, line, func, format, ...) \
-({ \
-	const int _nm_e = (error); \
-	const NMLogLevel _nm_l = _slog_level_to_nm ((level)); \
-	\
-	if (nm_logging_enabled (_nm_l, LOGD_SYSTEMD)) { \
-		const char *_nm_location = strrchr ((""file), '/'); \
-		\
-		_nm_log_impl (_nm_location ? _nm_location + 1 : (""file), (line), (func), _nm_l, LOGD_DHCP, _nm_e, NULL, NULL, ("%s"format), "libsystemd: ", ## __VA_ARGS__); \
-	} \
-	(_nm_e > 0 ? -_nm_e : _nm_e); \
-})
-
-#define log_assert_failed(text, file, line, func) \
-G_STMT_START { \
-	log_internal (LOG_CRIT, 0, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.", text, file, line, func); \
-	g_assert_not_reached (); \
-} G_STMT_END
-
-#define log_assert_failed_unreachable(text, file, line, func) \
-G_STMT_START { \
-	log_internal (LOG_CRIT, 0, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.", text, file, line, func); \
-	g_assert_not_reached (); \
-} G_STMT_END
-
-#define log_assert_failed_return(text, file, line, func) \
-({ \
-	log_internal (LOG_DEBUG, 0, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.", text, file, line, func); \
-	g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, text); \
-	(void) 0; \
-})
-
-/*****************************************************************************
- * The remainder of the header is only enabled when building the systemd code
- * itself.
- *****************************************************************************/
-
-#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD
-
-#include <netinet/in.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <elf.h>
-#ifdef HAVE_SYS_AUXV_H
-#include <sys/auxv.h>
-#endif
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/ioctl.h>
-
-#include <net/if_arp.h>
-
-/* Missing in Linux 3.2.0, in Ubuntu 12.04 */
-#ifndef BPF_XOR
-#define BPF_XOR 0xa0
-#endif
-
-#ifndef ETHERTYPE_LLDP
-#define ETHERTYPE_LLDP 0x88cc
-#endif
-
-#ifndef HAVE_SECURE_GETENV
-#  ifdef HAVE___SECURE_GETENV
-#    define secure_getenv __secure_getenv
-#  else
-#    error neither secure_getenv nor __secure_getenv is available
-#  endif
-#endif
-
-#define VALGRIND 0
-
-static inline pid_t
-raw_getpid (void) {
-#if defined(__alpha__)
-	return (pid_t) syscall (__NR_getxpid);
-#else
-	return (pid_t) syscall (__NR_getpid);
-#endif
-}
-
-/*****************************************************************************/
-
-/* work around missing uchar.h */
-typedef guint16 char16_t;
-typedef guint32 char32_t;
-
-/*****************************************************************************/
-
-static inline int
-sd_notify (int unset_environment, const char *state)
-{
-	return 0;
-}
-
-/* Can't include both net/if.h and linux/if.h; so have to define this here */
-#ifndef IF_NAMESIZE
-#define IF_NAMESIZE 16
-#endif
-
-#ifndef IFNAMSIZ
-#define IFNAMSIZ IF_NAMESIZE
-#endif
-
-#ifndef MAX_HANDLE_SZ
-#define MAX_HANDLE_SZ 128
-#endif
-
-#include "sd-id128.h"
-#include "sparse-endian.h"
-#include "async.h"
-#include "util.h"
-
-static inline pid_t gettid(void) {
-        return (pid_t) syscall(SYS_gettid);
-}
-
-#endif /* (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD */
-
-#endif /* NM_SD_ADAPT_H */
-
diff --git a/src/systemd/sd-adapt/procfs-util.h b/src/systemd/sd-adapt/procfs-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/procfs-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/raw-clone.h b/src/systemd/sd-adapt/raw-clone.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/raw-clone.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/terminal-util.h b/src/systemd/sd-adapt/terminal-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/terminal-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/unaligned.h b/src/systemd/sd-adapt/unaligned.h
deleted file mode 100644
index 17dc0444..00000000
--- a/src/systemd/sd-adapt/unaligned.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-#include "nm-utils/unaligned.h"
diff --git a/src/systemd/sd-adapt/user-util.h b/src/systemd/sd-adapt/user-util.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/user-util.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/sd-adapt/virt.h b/src/systemd/sd-adapt/virt.h
deleted file mode 100644
index 637892c2..00000000
--- a/src/systemd/sd-adapt/virt.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-/* dummy header */
diff --git a/src/systemd/src/basic/alloc-util.c b/src/systemd/src/basic/alloc-util.c
deleted file mode 100644
index ef405098..00000000
--- a/src/systemd/src/basic/alloc-util.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <stdint.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "macro.h"
-#include "util.h"
-
-void* memdup(const void *p, size_t l) {
-        void *ret;
-
-        assert(l == 0 || p);
-
-        ret = malloc(l);
-        if (!ret)
-                return NULL;
-
-        memcpy(ret, p, l);
-        return ret;
-}
-
-void* memdup_suffix0(const void *p, size_t l) {
-        void *ret;
-
-        assert(l == 0 || p);
-
-        /* The same as memdup() but place a safety NUL byte after the allocated memory */
-
-        ret = malloc(l + 1);
-        if (!ret)
-                return NULL;
-
-        *((uint8_t*) mempcpy(ret, p, l)) = 0;
-        return ret;
-}
-
-void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
-        size_t a, newalloc;
-        void *q;
-
-        assert(p);
-        assert(allocated);
-
-        if (*allocated >= need)
-                return *p;
-
-        newalloc = MAX(need * 2, 64u / size);
-        a = newalloc * size;
-
-        /* check for overflows */
-        if (a < size * need)
-                return NULL;
-
-        q = realloc(*p, a);
-        if (!q)
-                return NULL;
-
-        *p = q;
-        *allocated = newalloc;
-        return q;
-}
-
-void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
-        size_t prev;
-        uint8_t *q;
-
-        assert(p);
-        assert(allocated);
-
-        prev = *allocated;
-
-        q = greedy_realloc(p, allocated, need, size);
-        if (!q)
-                return NULL;
-
-        if (*allocated > prev)
-                memzero(q + prev * size, (*allocated - prev) * size);
-
-        return q;
-}
diff --git a/src/systemd/src/basic/alloc-util.h b/src/systemd/src/basic/alloc-util.h
deleted file mode 100644
index ebe42889..00000000
--- a/src/systemd/src/basic/alloc-util.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <alloca.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "macro.h"
-
-#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
-
-#define new0(t, n) ((t*) calloc((n), sizeof(t)))
-
-#define newa(t, n)                                              \
-        ({                                                      \
-                assert(!size_multiply_overflow(sizeof(t), n));  \
-                (t*) alloca(sizeof(t)*(n));                     \
-        })
-
-#define newa0(t, n)                                             \
-        ({                                                      \
-                assert(!size_multiply_overflow(sizeof(t), n));  \
-                (t*) alloca0(sizeof(t)*(n));                    \
-        })
-
-#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
-
-#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
-
-#define malloc0(n) (calloc(1, (n)))
-
-static inline void *mfree(void *memory) {
-        free(memory);
-        return NULL;
-}
-
-#define free_and_replace(a, b)                  \
-        ({                                      \
-                free(a);                        \
-                (a) = (b);                      \
-                (b) = NULL;                     \
-                0;                              \
-        })
-
-void* memdup(const void *p, size_t l) _alloc_(2);
-void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
-
-static inline void freep(void *p) {
-        free(*(void**) p);
-}
-
-#define _cleanup_free_ _cleanup_(freep)
-
-static inline bool size_multiply_overflow(size_t size, size_t need) {
-        return _unlikely_(need != 0 && size > (SIZE_MAX / need));
-}
-
-_malloc_  _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
-        if (size_multiply_overflow(size, need))
-                return NULL;
-
-        return malloc(size * need);
-}
-
-#if !HAVE_REALLOCARRAY
-_alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size) {
-        if (size_multiply_overflow(size, need))
-                return NULL;
-
-        return realloc(p, size * need);
-}
-#endif
-
-_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
-        if (size_multiply_overflow(size, need))
-                return NULL;
-
-        return memdup(p, size * need);
-}
-
-_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
-        if (size_multiply_overflow(size, need))
-                return NULL;
-
-        return memdup_suffix0(p, size * need);
-}
-
-void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
-void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
-
-#define GREEDY_REALLOC(array, allocated, need)                          \
-        greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
-
-#define GREEDY_REALLOC0(array, allocated, need)                         \
-        greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
-
-#define alloca0(n)                                      \
-        ({                                              \
-                char *_new_;                            \
-                size_t _len_ = n;                       \
-                _new_ = alloca(_len_);                  \
-                (void *) memset(_new_, 0, _len_);       \
-        })
-
-/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
-#define alloca_align(size, align)                                       \
-        ({                                                              \
-                void *_ptr_;                                            \
-                size_t _mask_ = (align) - 1;                            \
-                _ptr_ = alloca((size) + _mask_);                        \
-                (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \
-        })
-
-#define alloca0_align(size, align)                                      \
-        ({                                                              \
-                void *_new_;                                            \
-                size_t _size_ = (size);                                 \
-                _new_ = alloca_align(_size_, (align));                  \
-                (void*)memset(_new_, 0, _size_);                        \
-        })
-
-/* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to
- * NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */
-#define TAKE_PTR(ptr)                           \
-        ({                                      \
-                typeof(ptr) _ptr_ = (ptr);      \
-                (ptr) = NULL;                   \
-                _ptr_;                          \
-        })
diff --git a/src/systemd/src/basic/async.h b/src/systemd/src/basic/async.h
deleted file mode 100644
index 31606131..00000000
--- a/src/systemd/src/basic/async.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-int asynchronous_job(void* (*func)(void *p), void *arg);
-
-int asynchronous_sync(pid_t *ret_pid);
-int asynchronous_close(int fd);
diff --git a/src/systemd/src/basic/env-util.c b/src/systemd/src/basic/env-util.c
deleted file mode 100644
index 52d12a8a..00000000
--- a/src/systemd/src/basic/env-util.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "env-util.h"
-#include "escape.h"
-#include "extract-word.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "utf8.h"
-
-#if 0 /* NM_IGNORED */
-#define VALID_CHARS_ENV_NAME                    \
-        DIGITS LETTERS                          \
-        "_"
-
-#ifndef ARG_MAX
-#define ARG_MAX ((size_t) sysconf(_SC_ARG_MAX))
-#endif
-
-static bool env_name_is_valid_n(const char *e, size_t n) {
-        const char *p;
-
-        if (!e)
-                return false;
-
-        if (n <= 0)
-                return false;
-
-        if (e[0] >= '0' && e[0] <= '9')
-                return false;
-
-        /* POSIX says the overall size of the environment block cannot
-         * be > ARG_MAX, an individual assignment hence cannot be
-         * either. Discounting the equal sign and trailing NUL this
-         * hence leaves ARG_MAX-2 as longest possible variable
-         * name. */
-        if (n > ARG_MAX - 2)
-                return false;
-
-        for (p = e; p < e + n; p++)
-                if (!strchr(VALID_CHARS_ENV_NAME, *p))
-                        return false;
-
-        return true;
-}
-
-bool env_name_is_valid(const char *e) {
-        if (!e)
-                return false;
-
-        return env_name_is_valid_n(e, strlen(e));
-}
-
-bool env_value_is_valid(const char *e) {
-        if (!e)
-                return false;
-
-        if (!utf8_is_valid(e))
-                return false;
-
-        /* bash allows tabs and newlines in environment variables, and so
-         * should we */
-        if (string_has_cc(e, "\t\n"))
-                return false;
-
-        /* POSIX says the overall size of the environment block cannot
-         * be > ARG_MAX, an individual assignment hence cannot be
-         * either. Discounting the shortest possible variable name of
-         * length 1, the equal sign and trailing NUL this hence leaves
-         * ARG_MAX-3 as longest possible variable value. */
-        if (strlen(e) > ARG_MAX - 3)
-                return false;
-
-        return true;
-}
-
-bool env_assignment_is_valid(const char *e) {
-        const char *eq;
-
-        eq = strchr(e, '=');
-        if (!eq)
-                return false;
-
-        if (!env_name_is_valid_n(e, eq - e))
-                return false;
-
-        if (!env_value_is_valid(eq + 1))
-                return false;
-
-        /* POSIX says the overall size of the environment block cannot
-         * be > ARG_MAX, hence the individual variable assignments
-         * cannot be either, but let's leave room for one trailing NUL
-         * byte. */
-        if (strlen(e) > ARG_MAX - 1)
-                return false;
-
-        return true;
-}
-
-bool strv_env_is_valid(char **e) {
-        char **p, **q;
-
-        STRV_FOREACH(p, e) {
-                size_t k;
-
-                if (!env_assignment_is_valid(*p))
-                        return false;
-
-                /* Check if there are duplicate assginments */
-                k = strcspn(*p, "=");
-                STRV_FOREACH(q, p + 1)
-                        if (strneq(*p, *q, k) && (*q)[k] == '=')
-                                return false;
-        }
-
-        return true;
-}
-
-bool strv_env_name_is_valid(char **l) {
-        char **p, **q;
-
-        STRV_FOREACH(p, l) {
-                if (!env_name_is_valid(*p))
-                        return false;
-
-                STRV_FOREACH(q, p + 1)
-                        if (streq(*p, *q))
-                                return false;
-        }
-
-        return true;
-}
-
-bool strv_env_name_or_assignment_is_valid(char **l) {
-        char **p, **q;
-
-        STRV_FOREACH(p, l) {
-                if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p))
-                        return false;
-
-                STRV_FOREACH(q, p + 1)
-                        if (streq(*p, *q))
-                                return false;
-        }
-
-        return true;
-}
-
-static int env_append(char **r, char ***k, char **a) {
-        assert(r);
-        assert(k);
-
-        if (!a)
-                return 0;
-
-        /* Add the entries of a to *k unless they already exist in *r
-         * in which case they are overridden instead. This assumes
-         * there is enough space in the r array. */
-
-        for (; *a; a++) {
-                char **j;
-                size_t n;
-
-                n = strcspn(*a, "=");
-
-                if ((*a)[n] == '=')
-                        n++;
-
-                for (j = r; j < *k; j++)
-                        if (strneq(*j, *a, n))
-                                break;
-
-                if (j >= *k)
-                        (*k)++;
-                else
-                        free(*j);
-
-                *j = strdup(*a);
-                if (!*j)
-                        return -ENOMEM;
-        }
-
-        return 0;
-}
-
-char **strv_env_merge(size_t n_lists, ...) {
-        size_t n = 0;
-        char **l, **k, **r;
-        va_list ap;
-        size_t i;
-
-        /* Merges an arbitrary number of environment sets */
-
-        va_start(ap, n_lists);
-        for (i = 0; i < n_lists; i++) {
-                l = va_arg(ap, char**);
-                n += strv_length(l);
-        }
-        va_end(ap);
-
-        r = new(char*, n+1);
-        if (!r)
-                return NULL;
-
-        k = r;
-
-        va_start(ap, n_lists);
-        for (i = 0; i < n_lists; i++) {
-                l = va_arg(ap, char**);
-                if (env_append(r, &k, l) < 0)
-                        goto fail;
-        }
-        va_end(ap);
-
-        *k = NULL;
-
-        return r;
-
-fail:
-        va_end(ap);
-        strv_free(r);
-
-        return NULL;
-}
-
-static bool env_match(const char *t, const char *pattern) {
-        assert(t);
-        assert(pattern);
-
-        /* pattern a matches string a
-         *         a matches a=
-         *         a matches a=b
-         *         a= matches a=
-         *         a=b matches a=b
-         *         a= does not match a
-         *         a=b does not match a=
-         *         a=b does not match a
-         *         a=b does not match a=c */
-
-        if (streq(t, pattern))
-                return true;
-
-        if (!strchr(pattern, '=')) {
-                size_t l = strlen(pattern);
-
-                return strneq(t, pattern, l) && t[l] == '=';
-        }
-
-        return false;
-}
-
-static bool env_entry_has_name(const char *entry, const char *name) {
-        const char *t;
-
-        assert(entry);
-        assert(name);
-
-        t = startswith(entry, name);
-        if (!t)
-                return false;
-
-        return *t == '=';
-}
-
-char **strv_env_delete(char **x, size_t n_lists, ...) {
-        size_t n, i = 0;
-        char **k, **r;
-        va_list ap;
-
-        /* Deletes every entry from x that is mentioned in the other
-         * string lists */
-
-        n = strv_length(x);
-
-        r = new(char*, n+1);
-        if (!r)
-                return NULL;
-
-        STRV_FOREACH(k, x) {
-                size_t v;
-
-                va_start(ap, n_lists);
-                for (v = 0; v < n_lists; v++) {
-                        char **l, **j;
-
-                        l = va_arg(ap, char**);
-                        STRV_FOREACH(j, l)
-                                if (env_match(*k, *j))
-                                        goto skip;
-                }
-                va_end(ap);
-
-                r[i] = strdup(*k);
-                if (!r[i]) {
-                        strv_free(r);
-                        return NULL;
-                }
-
-                i++;
-                continue;
-
-        skip:
-                va_end(ap);
-        }
-
-        r[i] = NULL;
-
-        assert(i <= n);
-
-        return r;
-}
-
-char **strv_env_unset(char **l, const char *p) {
-
-        char **f, **t;
-
-        if (!l)
-                return NULL;
-
-        assert(p);
-
-        /* Drops every occurrence of the env var setting p in the
-         * string list. Edits in-place. */
-
-        for (f = t = l; *f; f++) {
-
-                if (env_match(*f, p)) {
-                        free(*f);
-                        continue;
-                }
-
-                *(t++) = *f;
-        }
-
-        *t = NULL;
-        return l;
-}
-
-char **strv_env_unset_many(char **l, ...) {
-
-        char **f, **t;
-
-        if (!l)
-                return NULL;
-
-        /* Like strv_env_unset() but applies many at once. Edits in-place. */
-
-        for (f = t = l; *f; f++) {
-                bool found = false;
-                const char *p;
-                va_list ap;
-
-                va_start(ap, l);
-
-                while ((p = va_arg(ap, const char*))) {
-                        if (env_match(*f, p)) {
-                                found = true;
-                                break;
-                        }
-                }
-
-                va_end(ap);
-
-                if (found) {
-                        free(*f);
-                        continue;
-                }
-
-                *(t++) = *f;
-        }
-
-        *t = NULL;
-        return l;
-}
-
-int strv_env_replace(char ***l, char *p) {
-        char **f;
-        const char *t, *name;
-
-        assert(p);
-
-        /* Replace first occurrence of the env var or add a new one in the
-         * string list. Drop other occurences. Edits in-place. Does not copy p.
-         * p must be a valid key=value assignment.
-         */
-
-        t = strchr(p, '=');
-        assert(t);
-
-        name = strndupa(p, t - p);
-
-        for (f = *l; f && *f; f++)
-                if (env_entry_has_name(*f, name)) {
-                        free_and_replace(*f, p);
-                        strv_env_unset(f + 1, *f);
-                        return 0;
-                }
-
-        /* We didn't find a match, we need to append p or create a new strv */
-        if (strv_push(l, p) < 0)
-                return -ENOMEM;
-        return 1;
-}
-
-char **strv_env_set(char **x, const char *p) {
-
-        char **k;
-        _cleanup_strv_free_ char **r = NULL;
-        char* m[2] = { (char*) p, NULL };
-
-        /* Overrides the env var setting of p, returns a new copy */
-
-        r = new(char*, strv_length(x)+2);
-        if (!r)
-                return NULL;
-
-        k = r;
-        if (env_append(r, &k, x) < 0)
-                return NULL;
-
-        if (env_append(r, &k, m) < 0)
-                return NULL;
-
-        *k = NULL;
-
-        return TAKE_PTR(r);
-}
-
-char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
-        char **i;
-
-        assert(name);
-
-        if (k <= 0)
-                return NULL;
-
-        STRV_FOREACH_BACKWARDS(i, l)
-                if (strneq(*i, name, k) &&
-                    (*i)[k] == '=')
-                        return *i + k + 1;
-
-        if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
-                const char *t;
-
-                t = strndupa(name, k);
-                return getenv(t);
-        };
-
-        return NULL;
-}
-
-char *strv_env_get(char **l, const char *name) {
-        assert(name);
-
-        return strv_env_get_n(l, name, strlen(name), 0);
-}
-
-char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) {
-        char **p, **q;
-        int k = 0;
-
-        STRV_FOREACH(p, e) {
-                size_t n;
-                bool duplicate = false;
-
-                if (!env_assignment_is_valid(*p)) {
-                        if (invalid_callback)
-                                invalid_callback(*p, userdata);
-                        free(*p);
-                        continue;
-                }
-
-                n = strcspn(*p, "=");
-                STRV_FOREACH(q, p + 1)
-                        if (strneq(*p, *q, n) && (*q)[n] == '=') {
-                                duplicate = true;
-                                break;
-                        }
-
-                if (duplicate) {
-                        free(*p);
-                        continue;
-                }
-
-                e[k++] = *p;
-        }
-
-        if (e)
-                e[k] = NULL;
-
-        return e;
-}
-
-char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
-        enum {
-                WORD,
-                CURLY,
-                VARIABLE,
-                VARIABLE_RAW,
-                TEST,
-                DEFAULT_VALUE,
-                ALTERNATE_VALUE,
-        } state = WORD;
-
-        const char *e, *word = format, *test_value;
-        char *k;
-        _cleanup_free_ char *r = NULL;
-        size_t i, len;
-        int nest = 0;
-
-        assert(format);
-
-        for (e = format, i = 0; *e && i < n; e ++, i ++)
-                switch (state) {
-
-                case WORD:
-                        if (*e == '$')
-                                state = CURLY;
-                        break;
-
-                case CURLY:
-                        if (*e == '{') {
-                                k = strnappend(r, word, e-word-1);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e-1;
-                                state = VARIABLE;
-                                nest++;
-                        } else if (*e == '$') {
-                                k = strnappend(r, word, e-word);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e+1;
-                                state = WORD;
-
-                        } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
-                                k = strnappend(r, word, e-word-1);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e-1;
-                                state = VARIABLE_RAW;
-
-                        } else
-                                state = WORD;
-                        break;
-
-                case VARIABLE:
-                        if (*e == '}') {
-                                const char *t;
-
-                                t = strv_env_get_n(env, word+2, e-word-2, flags);
-
-                                k = strappend(r, t);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e+1;
-                                state = WORD;
-                        } else if (*e == ':') {
-                                if (!(flags & REPLACE_ENV_ALLOW_EXTENDED))
-                                        /* Treat this as unsupported syntax, i.e. do no replacement */
-                                        state = WORD;
-                                else {
-                                        len = e-word-2;
-                                        state = TEST;
-                                }
-                        }
-                        break;
-
-                case TEST:
-                        if (*e == '-')
-                                state = DEFAULT_VALUE;
-                        else if (*e == '+')
-                                state = ALTERNATE_VALUE;
-                        else {
-                                state = WORD;
-                                break;
-                        }
-
-                        test_value = e+1;
-                        break;
-
-                case DEFAULT_VALUE: /* fall through */
-                case ALTERNATE_VALUE:
-                        assert(flags & REPLACE_ENV_ALLOW_EXTENDED);
-
-                        if (*e == '{') {
-                                nest++;
-                                break;
-                        }
-
-                        if (*e != '}')
-                                break;
-
-                        nest--;
-                        if (nest == 0) {
-                                const char *t;
-                                _cleanup_free_ char *v = NULL;
-
-                                t = strv_env_get_n(env, word+2, len, flags);
-
-                                if (t && state == ALTERNATE_VALUE)
-                                        t = v = replace_env_n(test_value, e-test_value, env, flags);
-                                else if (!t && state == DEFAULT_VALUE)
-                                        t = v = replace_env_n(test_value, e-test_value, env, flags);
-
-                                k = strappend(r, t);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e+1;
-                                state = WORD;
-                        }
-                        break;
-
-                case VARIABLE_RAW:
-                        assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
-
-                        if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
-                                const char *t;
-
-                                t = strv_env_get_n(env, word+1, e-word-1, flags);
-
-                                k = strappend(r, t);
-                                if (!k)
-                                        return NULL;
-
-                                free_and_replace(r, k);
-
-                                word = e--;
-                                i--;
-                                state = WORD;
-                        }
-                        break;
-                }
-
-        if (state == VARIABLE_RAW) {
-                const char *t;
-
-                assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
-
-                t = strv_env_get_n(env, word+1, e-word-1, flags);
-                return strappend(r, t);
-        } else
-                return strnappend(r, word, e-word);
-}
-
-char **replace_env_argv(char **argv, char **env) {
-        char **ret, **i;
-        size_t k = 0, l = 0;
-
-        l = strv_length(argv);
-
-        ret = new(char*, l+1);
-        if (!ret)
-                return NULL;
-
-        STRV_FOREACH(i, argv) {
-
-                /* If $FOO appears as single word, replace it by the split up variable */
-                if ((*i)[0] == '$' && !IN_SET((*i)[1], '{', '$')) {
-                        char *e;
-                        char **w, **m = NULL;
-                        size_t q;
-
-                        e = strv_env_get(env, *i+1);
-                        if (e) {
-                                int r;
-
-                                r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES);
-                                if (r < 0) {
-                                        ret[k] = NULL;
-                                        strv_free(ret);
-                                        return NULL;
-                                }
-                        } else
-                                m = NULL;
-
-                        q = strv_length(m);
-                        l = l + q - 1;
-
-                        w = reallocarray(ret, l + 1, sizeof(char *));
-                        if (!w) {
-                                ret[k] = NULL;
-                                strv_free(ret);
-                                strv_free(m);
-                                return NULL;
-                        }
-
-                        ret = w;
-                        if (m) {
-                                memcpy(ret + k, m, q * sizeof(char*));
-                                free(m);
-                        }
-
-                        k += q;
-                        continue;
-                }
-
-                /* If ${FOO} appears as part of a word, replace it by the variable as-is */
-                ret[k] = replace_env(*i, env, 0);
-                if (!ret[k]) {
-                        strv_free(ret);
-                        return NULL;
-                }
-                k++;
-        }
-
-        ret[k] = NULL;
-        return ret;
-}
-#endif /* NM_IGNORED */
-
-int getenv_bool(const char *p) {
-        const char *e;
-
-        e = getenv(p);
-        if (!e)
-                return -ENXIO;
-
-        return parse_boolean(e);
-}
-
-#if 0 /* NM_IGNORED */
-int getenv_bool_secure(const char *p) {
-        const char *e;
-
-        e = secure_getenv(p);
-        if (!e)
-                return -ENXIO;
-
-        return parse_boolean(e);
-}
-
-int serialize_environment(FILE *f, char **environment) {
-        char **e;
-
-        STRV_FOREACH(e, environment) {
-                _cleanup_free_ char *ce;
-
-                ce = cescape(*e);
-                if (!ce)
-                        return -ENOMEM;
-
-                fprintf(f, "env=%s\n", ce);
-        }
-
-        /* caller should call ferror() */
-
-        return 0;
-}
-
-int deserialize_environment(char ***environment, const char *line) {
-        char *uce;
-        int r;
-
-        assert(line);
-        assert(environment);
-
-        assert(startswith(line, "env="));
-        r = cunescape(line + 4, 0, &uce);
-        if (r < 0)
-                return r;
-
-        return strv_env_replace(environment, uce);
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/env-util.h b/src/systemd/src/basic/env-util.h
deleted file mode 100644
index 174433ea..00000000
--- a/src/systemd/src/basic/env-util.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include "macro.h"
-#include "string.h"
-
-bool env_name_is_valid(const char *e);
-bool env_value_is_valid(const char *e);
-bool env_assignment_is_valid(const char *e);
-
-enum {
-        REPLACE_ENV_USE_ENVIRONMENT = 1u,
-        REPLACE_ENV_ALLOW_BRACELESS = 2u,
-        REPLACE_ENV_ALLOW_EXTENDED  = 4u,
-};
-
-char *replace_env_n(const char *format, size_t n, char **env, unsigned flags);
-char **replace_env_argv(char **argv, char **env);
-
-static inline char *replace_env(const char *format, char **env, unsigned flags) {
-        return replace_env_n(format, strlen(format), env, flags);
-}
-
-bool strv_env_is_valid(char **e);
-#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
-char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
-
-bool strv_env_name_is_valid(char **l);
-bool strv_env_name_or_assignment_is_valid(char **l);
-
-char **strv_env_merge(size_t n_lists, ...);
-char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */
-
-char **strv_env_set(char **x, const char *p); /* New copy ... */
-char **strv_env_unset(char **l, const char *p); /* In place ... */
-char **strv_env_unset_many(char **l, ...) _sentinel_;
-int strv_env_replace(char ***l, char *p); /* In place ... */
-
-char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
-char *strv_env_get(char **x, const char *n) _pure_;
-
-int getenv_bool(const char *p);
-int getenv_bool_secure(const char *p);
-
-int serialize_environment(FILE *f, char **environment);
-int deserialize_environment(char ***environment, const char *line);
diff --git a/src/systemd/src/basic/escape.c b/src/systemd/src/basic/escape.c
deleted file mode 100644
index 5c82a545..00000000
--- a/src/systemd/src/basic/escape.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "escape.h"
-#include "hexdecoct.h"
-#include "macro.h"
-#include "utf8.h"
-
-int cescape_char(char c, char *buf) {
-        char *buf_old = buf;
-
-        /* Needs space for 4 characters in the buffer */
-
-        switch (c) {
-
-                case '\a':
-                        *(buf++) = '\\';
-                        *(buf++) = 'a';
-                        break;
-                case '\b':
-                        *(buf++) = '\\';
-                        *(buf++) = 'b';
-                        break;
-                case '\f':
-                        *(buf++) = '\\';
-                        *(buf++) = 'f';
-                        break;
-                case '\n':
-                        *(buf++) = '\\';
-                        *(buf++) = 'n';
-                        break;
-                case '\r':
-                        *(buf++) = '\\';
-                        *(buf++) = 'r';
-                        break;
-                case '\t':
-                        *(buf++) = '\\';
-                        *(buf++) = 't';
-                        break;
-                case '\v':
-                        *(buf++) = '\\';
-                        *(buf++) = 'v';
-                        break;
-                case '\\':
-                        *(buf++) = '\\';
-                        *(buf++) = '\\';
-                        break;
-                case '"':
-                        *(buf++) = '\\';
-                        *(buf++) = '"';
-                        break;
-                case '\'':
-                        *(buf++) = '\\';
-                        *(buf++) = '\'';
-                        break;
-
-                default:
-                        /* For special chars we prefer octal over
-                         * hexadecimal encoding, simply because glib's
-                         * g_strescape() does the same */
-                        if ((c < ' ') || (c >= 127)) {
-                                *(buf++) = '\\';
-                                *(buf++) = octchar((unsigned char) c >> 6);
-                                *(buf++) = octchar((unsigned char) c >> 3);
-                                *(buf++) = octchar((unsigned char) c);
-                        } else
-                                *(buf++) = c;
-                        break;
-        }
-
-        return buf - buf_old;
-}
-
-char *cescape_length(const char *s, size_t n) {
-        const char *f;
-        char *r, *t;
-
-        assert(s || n == 0);
-
-        /* Does C style string escaping. May be reversed with
-         * cunescape(). */
-
-        r = new(char, n*4 + 1);
-        if (!r)
-                return NULL;
-
-        for (f = s, t = r; f < s + n; f++)
-                t += cescape_char(*f, t);
-
-        *t = 0;
-
-        return r;
-}
-
-char *cescape(const char *s) {
-        assert(s);
-
-        return cescape_length(s, strlen(s));
-}
-
-int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) {
-        int r = 1;
-
-        assert(p);
-        assert(*p);
-        assert(ret);
-
-        /* Unescapes C style. Returns the unescaped character in ret.
-         * Sets *eight_bit to true if the escaped sequence either fits in
-         * one byte in UTF-8 or is a non-unicode literal byte and should
-         * instead be copied directly.
-         */
-
-        if (length != (size_t) -1 && length < 1)
-                return -EINVAL;
-
-        switch (p[0]) {
-
-        case 'a':
-                *ret = '\a';
-                break;
-        case 'b':
-                *ret = '\b';
-                break;
-        case 'f':
-                *ret = '\f';
-                break;
-        case 'n':
-                *ret = '\n';
-                break;
-        case 'r':
-                *ret = '\r';
-                break;
-        case 't':
-                *ret = '\t';
-                break;
-        case 'v':
-                *ret = '\v';
-                break;
-        case '\\':
-                *ret = '\\';
-                break;
-        case '"':
-                *ret = '"';
-                break;
-        case '\'':
-                *ret = '\'';
-                break;
-
-        case 's':
-                /* This is an extension of the XDG syntax files */
-                *ret = ' ';
-                break;
-
-        case 'x': {
-                /* hexadecimal encoding */
-                int a, b;
-
-                if (length != (size_t) -1 && length < 3)
-                        return -EINVAL;
-
-                a = unhexchar(p[1]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unhexchar(p[2]);
-                if (b < 0)
-                        return -EINVAL;
-
-                /* Don't allow NUL bytes */
-                if (a == 0 && b == 0)
-                        return -EINVAL;
-
-                *ret = (a << 4U) | b;
-                *eight_bit = true;
-                r = 3;
-                break;
-        }
-
-        case 'u': {
-                /* C++11 style 16bit unicode */
-
-                int a[4];
-                size_t i;
-                uint32_t c;
-
-                if (length != (size_t) -1 && length < 5)
-                        return -EINVAL;
-
-                for (i = 0; i < 4; i++) {
-                        a[i] = unhexchar(p[1 + i]);
-                        if (a[i] < 0)
-                                return a[i];
-                }
-
-                c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
-
-                /* Don't allow 0 chars */
-                if (c == 0)
-                        return -EINVAL;
-
-                *ret = c;
-                r = 5;
-                break;
-        }
-
-        case 'U': {
-                /* C++11 style 32bit unicode */
-
-                int a[8];
-                size_t i;
-                char32_t c;
-
-                if (length != (size_t) -1 && length < 9)
-                        return -EINVAL;
-
-                for (i = 0; i < 8; i++) {
-                        a[i] = unhexchar(p[1 + i]);
-                        if (a[i] < 0)
-                                return a[i];
-                }
-
-                c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
-                    ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] <<  8U) | ((uint32_t) a[6] <<  4U) |  (uint32_t) a[7];
-
-                /* Don't allow 0 chars */
-                if (c == 0)
-                        return -EINVAL;
-
-                /* Don't allow invalid code points */
-                if (!unichar_is_valid(c))
-                        return -EINVAL;
-
-                *ret = c;
-                r = 9;
-                break;
-        }
-
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7': {
-                /* octal encoding */
-                int a, b, c;
-                char32_t m;
-
-                if (length != (size_t) -1 && length < 3)
-                        return -EINVAL;
-
-                a = unoctchar(p[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unoctchar(p[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                c = unoctchar(p[2]);
-                if (c < 0)
-                        return -EINVAL;
-
-                /* don't allow NUL bytes */
-                if (a == 0 && b == 0 && c == 0)
-                        return -EINVAL;
-
-                /* Don't allow bytes above 255 */
-                m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
-                if (m > 255)
-                        return -EINVAL;
-
-                *ret = m;
-                *eight_bit = true;
-                r = 3;
-                break;
-        }
-
-        default:
-                return -EINVAL;
-        }
-
-        return r;
-}
-
-int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
-        char *r, *t;
-        const char *f;
-        size_t pl;
-
-        assert(s);
-        assert(ret);
-
-        /* Undoes C style string escaping, and optionally prefixes it. */
-
-        pl = strlen_ptr(prefix);
-
-        r = new(char, pl+length+1);
-        if (!r)
-                return -ENOMEM;
-
-        if (prefix)
-                memcpy(r, prefix, pl);
-
-        for (f = s, t = r + pl; f < s + length; f++) {
-                size_t remaining;
-                bool eight_bit = false;
-                char32_t u;
-                int k;
-
-                remaining = s + length - f;
-                assert(remaining > 0);
-
-                if (*f != '\\') {
-                        /* A literal, copy verbatim */
-                        *(t++) = *f;
-                        continue;
-                }
-
-                if (remaining == 1) {
-                        if (flags & UNESCAPE_RELAX) {
-                                /* A trailing backslash, copy verbatim */
-                                *(t++) = *f;
-                                continue;
-                        }
-
-                        free(r);
-                        return -EINVAL;
-                }
-
-                k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit);
-                if (k < 0) {
-                        if (flags & UNESCAPE_RELAX) {
-                                /* Invalid escape code, let's take it literal then */
-                                *(t++) = '\\';
-                                continue;
-                        }
-
-                        free(r);
-                        return k;
-                }
-
-                f += k;
-                if (eight_bit)
-                        /* One byte? Set directly as specified */
-                        *(t++) = u;
-                else
-                        /* Otherwise encode as multi-byte UTF-8 */
-                        t += utf8_encode_unichar(t, u);
-        }
-
-        *t = 0;
-
-        *ret = r;
-        return t - r;
-}
-
-int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
-        return cunescape_length_with_prefix(s, length, NULL, flags, ret);
-}
-
-int cunescape(const char *s, UnescapeFlags flags, char **ret) {
-        return cunescape_length(s, strlen(s), flags, ret);
-}
-
-char *xescape(const char *s, const char *bad) {
-        char *r, *t;
-        const char *f;
-
-        /* Escapes all chars in bad, in addition to \ and all special
-         * chars, in \xFF style escaping. May be reversed with
-         * cunescape(). */
-
-        r = new(char, strlen(s) * 4 + 1);
-        if (!r)
-                return NULL;
-
-        for (f = s, t = r; *f; f++) {
-
-                if ((*f < ' ') || (*f >= 127) ||
-                    (*f == '\\') || strchr(bad, *f)) {
-                        *(t++) = '\\';
-                        *(t++) = 'x';
-                        *(t++) = hexchar(*f >> 4);
-                        *(t++) = hexchar(*f);
-                } else
-                        *(t++) = *f;
-        }
-
-        *t = 0;
-
-        return r;
-}
-
-char *octescape(const char *s, size_t len) {
-        char *r, *t;
-        const char *f;
-
-        /* Escapes all chars in bad, in addition to \ and " chars,
-         * in \nnn style escaping. */
-
-        r = new(char, len * 4 + 1);
-        if (!r)
-                return NULL;
-
-        for (f = s, t = r; f < s + len; f++) {
-
-                if (*f < ' ' || *f >= 127 || IN_SET(*f, '\\', '"')) {
-                        *(t++) = '\\';
-                        *(t++) = '0' + (*f >> 6);
-                        *(t++) = '0' + ((*f >> 3) & 8);
-                        *(t++) = '0' + (*f & 8);
-                } else
-                        *(t++) = *f;
-        }
-
-        *t = 0;
-
-        return r;
-
-}
-
-static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
-        assert(bad);
-
-        for (; *s; s++) {
-                if (escape_tab_nl && IN_SET(*s, '\n', '\t')) {
-                        *(t++) = '\\';
-                        *(t++) = *s == '\n' ? 'n' : 't';
-                        continue;
-                }
-
-                if (*s == '\\' || strchr(bad, *s))
-                        *(t++) = '\\';
-
-                *(t++) = *s;
-        }
-
-        return t;
-}
-
-char *shell_escape(const char *s, const char *bad) {
-        char *r, *t;
-
-        r = new(char, strlen(s)*2+1);
-        if (!r)
-                return NULL;
-
-        t = strcpy_backslash_escaped(r, s, bad, false);
-        *t = 0;
-
-        return r;
-}
-
-char* shell_maybe_quote(const char *s, EscapeStyle style) {
-        const char *p;
-        char *r, *t;
-
-        assert(s);
-
-        /* Encloses a string in quotes if necessary to make it OK as a shell
-         * string. Note that we treat benign UTF-8 characters as needing
-         * escaping too, but that should be OK. */
-
-        for (p = s; *p; p++)
-                if (*p <= ' ' ||
-                    *p >= 127 ||
-                    strchr(SHELL_NEED_QUOTES, *p))
-                        break;
-
-        if (!*p)
-                return strdup(s);
-
-        r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
-        if (!r)
-                return NULL;
-
-        t = r;
-        if (style == ESCAPE_BACKSLASH)
-                *(t++) = '"';
-        else if (style == ESCAPE_POSIX) {
-                *(t++) = '$';
-                *(t++) = '\'';
-        } else
-                assert_not_reached("Bad EscapeStyle");
-
-        t = mempcpy(t, s, p - s);
-
-        if (style == ESCAPE_BACKSLASH)
-                t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false);
-        else
-                t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
-
-        if (style == ESCAPE_BACKSLASH)
-                *(t++) = '"';
-        else
-                *(t++) = '\'';
-        *t = 0;
-
-        return r;
-}
diff --git a/src/systemd/src/basic/escape.h b/src/systemd/src/basic/escape.h
deleted file mode 100644
index c612a7c0..00000000
--- a/src/systemd/src/basic/escape.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-#if 0 /* NM_IGNORED */
-#include <uchar.h>
-#endif /* NM_IGNORED */
-
-#include "string-util.h"
-#include "missing.h"
-
-/* What characters are special in the shell? */
-/* must be escaped outside and inside double-quotes */
-#define SHELL_NEED_ESCAPE "\"\\`$"
-
-/* Those that can be escaped or double-quoted.
- *
- * Stricly speaking, ! does not need to be escaped, except in interactive
- * mode, but let's be extra nice to the user and quote ! in case this
- * output is ever used in interactive mode. */
-#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
-
-/* Note that we assume control characters would need to be escaped too in
- * addition to the "special" characters listed here, if they appear in the
- * string. Current users disallow control characters. Also '"' shall not
- * be escaped.
- */
-#define SHELL_NEED_ESCAPE_POSIX "\\\'"
-
-typedef enum UnescapeFlags {
-        UNESCAPE_RELAX = 1,
-} UnescapeFlags;
-
-typedef enum EscapeStyle {
-        ESCAPE_BACKSLASH = 1,
-        ESCAPE_POSIX = 2,
-} EscapeStyle;
-
-char *cescape(const char *s);
-char *cescape_length(const char *s, size_t n);
-int cescape_char(char c, char *buf);
-
-int cunescape(const char *s, UnescapeFlags flags, char **ret);
-int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
-int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
-int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
-
-char *xescape(const char *s, const char *bad);
-char *octescape(const char *s, size_t len);
-
-char *shell_escape(const char *s, const char *bad);
-char* shell_maybe_quote(const char *s, EscapeStyle style);
diff --git a/src/systemd/src/basic/ether-addr-util.c b/src/systemd/src/basic/ether-addr-util.c
deleted file mode 100644
index ed92bc60..00000000
--- a/src/systemd/src/basic/ether-addr-util.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <net/ethernet.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "ether-addr-util.h"
-#include "macro.h"
-#include "string-util.h"
-
-char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
-        assert(addr);
-        assert(buffer);
-
-        /* Like ether_ntoa() but uses %02x instead of %x to print
-         * ethernet addresses, which makes them look less funny. Also,
-         * doesn't use a static buffer. */
-
-        sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
-                addr->ether_addr_octet[0],
-                addr->ether_addr_octet[1],
-                addr->ether_addr_octet[2],
-                addr->ether_addr_octet[3],
-                addr->ether_addr_octet[4],
-                addr->ether_addr_octet[5]);
-
-        return buffer;
-}
-
-int ether_addr_compare(const void *a, const void *b) {
-        assert(a);
-        assert(b);
-
-        return memcmp(a, b, ETH_ALEN);
-}
-
-static void ether_addr_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(p, sizeof(struct ether_addr), state);
-}
-
-const struct hash_ops ether_addr_hash_ops = {
-        .hash = ether_addr_hash_func,
-        .compare = ether_addr_compare
-};
-
-int ether_addr_from_string(const char *s, struct ether_addr *ret) {
-        size_t pos = 0, n, field;
-        char sep = '\0';
-        const char *hex = HEXDIGITS, *hexoff;
-        size_t x;
-        bool touched;
-
-#define parse_fields(v)                                         \
-        for (field = 0; field < ELEMENTSOF(v); field++) {       \
-                touched = false;                                \
-                for (n = 0; n < (2 * sizeof(v[0])); n++) {      \
-                        if (s[pos] == '\0')                     \
-                                break;                          \
-                        hexoff = strchr(hex, s[pos]);           \
-                        if (!hexoff)                            \
-                                break;                          \
-                        assert(hexoff >= hex);                  \
-                        x = hexoff - hex;                       \
-                        if (x >= 16)                            \
-                                x -= 6; /* A-F */               \
-                        assert(x < 16);                         \
-                        touched = true;                         \
-                        v[field] <<= 4;                         \
-                        v[field] += x;                          \
-                        pos++;                                  \
-                }                                               \
-                if (!touched)                                   \
-                        return -EINVAL;                         \
-                if (field < (ELEMENTSOF(v)-1)) {                \
-                        if (s[pos] != sep)                      \
-                                return -EINVAL;                 \
-                        else                                    \
-                                pos++;                          \
-                }                                               \
-        }
-
-        assert(s);
-        assert(ret);
-
-        s += strspn(s, WHITESPACE);
-        sep = s[strspn(s, hex)];
-
-        if (sep == '.') {
-                uint16_t shorts[3] = { 0 };
-
-                parse_fields(shorts);
-
-                if (s[pos] != '\0')
-                        return -EINVAL;
-
-                for (n = 0; n < ELEMENTSOF(shorts); n++) {
-                        ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
-                        ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
-                }
-
-        } else if (IN_SET(sep, ':', '-')) {
-                struct ether_addr out = ETHER_ADDR_NULL;
-
-                parse_fields(out.ether_addr_octet);
-
-                if (s[pos] != '\0')
-                        return -EINVAL;
-
-                for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
-                        ret->ether_addr_octet[n] = out.ether_addr_octet[n];
-
-        } else
-                return -EINVAL;
-
-        return 0;
-}
diff --git a/src/systemd/src/basic/ether-addr-util.h b/src/systemd/src/basic/ether-addr-util.h
deleted file mode 100644
index 3be03700..00000000
--- a/src/systemd/src/basic/ether-addr-util.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <net/ethernet.h>
-#include <stdbool.h>
-
-#include "hash-funcs.h"
-
-#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
-#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
-
-#define ETHER_ADDR_TO_STRING_MAX (3*6)
-char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
-
-int ether_addr_compare(const void *a, const void *b);
-static inline bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
-        return ether_addr_compare(a, b) == 0;
-}
-
-#define ETHER_ADDR_NULL ((const struct ether_addr){})
-
-static inline bool ether_addr_is_null(const struct ether_addr *addr) {
-        return ether_addr_equal(addr, &ETHER_ADDR_NULL);
-}
-
-int ether_addr_from_string(const char *s, struct ether_addr *ret);
-
-extern const struct hash_ops ether_addr_hash_ops;
diff --git a/src/systemd/src/basic/extract-word.c b/src/systemd/src/basic/extract-word.c
deleted file mode 100644
index 404fe615..00000000
--- a/src/systemd/src/basic/extract-word.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "alloc-util.h"
-#include "escape.h"
-#include "extract-word.h"
-#include "log.h"
-#include "macro.h"
-#include "string-util.h"
-#include "utf8.h"
-
-int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
-        _cleanup_free_ char *s = NULL;
-        size_t allocated = 0, sz = 0;
-        char c;
-        int r;
-
-        char quote = 0;                 /* 0 or ' or " */
-        bool backslash = false;         /* whether we've just seen a backslash */
-
-        assert(p);
-        assert(ret);
-
-        /* Bail early if called after last value or with no input */
-        if (!*p)
-                goto finish;
-        c = **p;
-
-        if (!separators)
-                separators = WHITESPACE;
-
-        /* Parses the first word of a string, and returns it in
-         * *ret. Removes all quotes in the process. When parsing fails
-         * (because of an uneven number of quotes or similar), leaves
-         * the pointer *p at the first invalid character. */
-
-        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
-                if (!GREEDY_REALLOC(s, allocated, sz+1))
-                        return -ENOMEM;
-
-        for (;; (*p)++, c = **p) {
-                if (c == 0)
-                        goto finish_force_terminate;
-                else if (strchr(separators, c)) {
-                        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
-                                (*p)++;
-                                goto finish_force_next;
-                        }
-                } else {
-                        /* We found a non-blank character, so we will always
-                         * want to return a string (even if it is empty),
-                         * allocate it here. */
-                        if (!GREEDY_REALLOC(s, allocated, sz+1))
-                                return -ENOMEM;
-                        break;
-                }
-        }
-
-        for (;; (*p)++, c = **p) {
-                if (backslash) {
-                        if (!GREEDY_REALLOC(s, allocated, sz+7))
-                                return -ENOMEM;
-
-                        if (c == 0) {
-                                if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
-                                    (!quote || flags & EXTRACT_RELAX)) {
-                                        /* If we find an unquoted trailing backslash and we're in
-                                         * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
-                                         * output.
-                                         *
-                                         * Unbalanced quotes will only be allowed in EXTRACT_RELAX
-                                         * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
-                                         */
-                                        s[sz++] = '\\';
-                                        goto finish_force_terminate;
-                                }
-                                if (flags & EXTRACT_RELAX)
-                                        goto finish_force_terminate;
-                                return -EINVAL;
-                        }
-
-                        if (flags & EXTRACT_CUNESCAPE) {
-                                bool eight_bit = false;
-                                char32_t u;
-
-                                r = cunescape_one(*p, (size_t) -1, &u, &eight_bit);
-                                if (r < 0) {
-                                        if (flags & EXTRACT_CUNESCAPE_RELAX) {
-                                                s[sz++] = '\\';
-                                                s[sz++] = c;
-                                        } else
-                                                return -EINVAL;
-                                } else {
-                                        (*p) += r - 1;
-
-                                        if (eight_bit)
-                                                s[sz++] = u;
-                                        else
-                                                sz += utf8_encode_unichar(s + sz, u);
-                                }
-                        } else
-                                s[sz++] = c;
-
-                        backslash = false;
-
-                } else if (quote) {     /* inside either single or double quotes */
-                        for (;; (*p)++, c = **p) {
-                                if (c == 0) {
-                                        if (flags & EXTRACT_RELAX)
-                                                goto finish_force_terminate;
-                                        return -EINVAL;
-                                } else if (c == quote) {        /* found the end quote */
-                                        quote = 0;
-                                        break;
-                                } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
-                                        backslash = true;
-                                        break;
-                                } else {
-                                        if (!GREEDY_REALLOC(s, allocated, sz+2))
-                                                return -ENOMEM;
-
-                                        s[sz++] = c;
-                                }
-                        }
-
-                } else {
-                        for (;; (*p)++, c = **p) {
-                                if (c == 0)
-                                        goto finish_force_terminate;
-                                else if (IN_SET(c, '\'', '"') && (flags & EXTRACT_QUOTES)) {
-                                        quote = c;
-                                        break;
-                                } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
-                                        backslash = true;
-                                        break;
-                                } else if (strchr(separators, c)) {
-                                        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
-                                                (*p)++;
-                                                goto finish_force_next;
-                                        }
-                                        /* Skip additional coalesced separators. */
-                                        for (;; (*p)++, c = **p) {
-                                                if (c == 0)
-                                                        goto finish_force_terminate;
-                                                if (!strchr(separators, c))
-                                                        break;
-                                        }
-                                        goto finish;
-
-                                } else {
-                                        if (!GREEDY_REALLOC(s, allocated, sz+2))
-                                                return -ENOMEM;
-
-                                        s[sz++] = c;
-                                }
-                        }
-                }
-        }
-
-finish_force_terminate:
-        *p = NULL;
-finish:
-        if (!s) {
-                *p = NULL;
-                *ret = NULL;
-                return 0;
-        }
-
-finish_force_next:
-        s[sz] = 0;
-        *ret = TAKE_PTR(s);
-
-        return 1;
-}
-
-#if 0 /* NM_IGNORED */
-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) {
-
-        /* Try to unquote it, if it fails, warn about it and try again
-         * but this time using EXTRACT_CUNESCAPE_RELAX to keep the
-         * backslashes verbatim in invalid escape sequences. */
-
-        const char *save;
-        int r;
-
-        save = *p;
-        r = extract_first_word(p, ret, separators, flags);
-        if (r >= 0)
-                return r;
-
-        if (r == -EINVAL && !(flags & EXTRACT_CUNESCAPE_RELAX)) {
-
-                /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
-                *p = save;
-                r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
-                if (r >= 0) {
-                        /* It worked this time, hence it must have been an invalid escape sequence. */
-                        log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Ignoring unknown escape sequences: \"%s\"", *ret);
-                        return r;
-                }
-
-                /* If it's still EINVAL; then it must be unbalanced quoting, report this. */
-                if (r == -EINVAL)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting, ignoring: \"%s\"", rvalue);
-        }
-
-        /* Can be any error, report it */
-        return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue);
-}
-
-/* We pass ExtractFlags as unsigned int (to avoid undefined behaviour when passing
- * an object that undergoes default argument promotion as an argument to va_start).
- * 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, ...) {
-        va_list ap;
-        char **l;
-        int n = 0, i, c, r;
-
-        /* 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;
-                n++;
-        }
-        va_end(ap);
-
-        if (n <= 0)
-                return 0;
-
-        /* Read all words into a temporary array */
-        l = newa0(char*, n);
-        for (c = 0; c < n; c++) {
-
-                r = extract_first_word(p, &l[c], separators, flags);
-                if (r < 0) {
-                        int j;
-
-                        for (j = 0; j < c; j++)
-                                free(l[j]);
-
-                        return r;
-                }
-
-                if (r == 0)
-                        break;
-        }
-
-        /* 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];
-        }
-        va_end(ap);
-
-        return c;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/extract-word.h b/src/systemd/src/basic/extract-word.h
deleted file mode 100644
index 8c63b7c3..00000000
--- a/src/systemd/src/basic/extract-word.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include "macro.h"
-
-typedef enum ExtractFlags {
-        EXTRACT_RELAX                    = 1,
-        EXTRACT_CUNESCAPE                = 2,
-        EXTRACT_CUNESCAPE_RELAX          = 4,
-        EXTRACT_QUOTES                   = 8,
-        EXTRACT_DONT_COALESCE_SEPARATORS = 16,
-        EXTRACT_RETAIN_ESCAPE            = 32,
-} 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_;
diff --git a/src/systemd/src/basic/fd-util.c b/src/systemd/src/basic/fd-util.c
deleted file mode 100644
index 71babe2f..00000000
--- a/src/systemd/src/basic/fd-util.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "copy.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "io-util.h"
-#include "macro.h"
-#include "memfd-util.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "socket-util.h"
-#include "stdio-util.h"
-#include "util.h"
-
-int close_nointr(int fd) {
-        assert(fd >= 0);
-
-        if (close(fd) >= 0)
-                return 0;
-
-        /*
-         * Just ignore EINTR; a retry loop is the wrong thing to do on
-         * Linux.
-         *
-         * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
-         * https://bugzilla.gnome.org/show_bug.cgi?id=682819
-         * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
-         * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
-         */
-        if (errno == EINTR)
-                return 0;
-
-        return -errno;
-}
-
-int safe_close(int fd) {
-
-        /*
-         * Like close_nointr() but cannot fail. Guarantees errno is
-         * unchanged. Is a NOP with negative fds passed, and returns
-         * -1, so that it can be used in this syntax:
-         *
-         * fd = safe_close(fd);
-         */
-
-        if (fd >= 0) {
-                PROTECT_ERRNO;
-
-                /* The kernel might return pretty much any error code
-                 * via close(), but the fd will be closed anyway. The
-                 * only condition we want to check for here is whether
-                 * the fd was invalid at all... */
-
-                assert_se(close_nointr(fd) != -EBADF);
-        }
-
-        return -1;
-}
-
-void safe_close_pair(int p[]) {
-        assert(p);
-
-        if (p[0] == p[1]) {
-                /* Special case pairs which use the same fd in both
-                 * directions... */
-                p[0] = p[1] = safe_close(p[0]);
-                return;
-        }
-
-        p[0] = safe_close(p[0]);
-        p[1] = safe_close(p[1]);
-}
-
-void close_many(const int fds[], size_t n_fd) {
-        size_t i;
-
-        assert(fds || n_fd <= 0);
-
-        for (i = 0; i < n_fd; i++)
-                safe_close(fds[i]);
-}
-
-int fclose_nointr(FILE *f) {
-        assert(f);
-
-        /* Same as close_nointr(), but for fclose() */
-
-        if (fclose(f) == 0)
-                return 0;
-
-        if (errno == EINTR)
-                return 0;
-
-        return -errno;
-}
-
-FILE* safe_fclose(FILE *f) {
-
-        /* Same as safe_close(), but for fclose() */
-
-        if (f) {
-                PROTECT_ERRNO;
-
-                assert_se(fclose_nointr(f) != EBADF);
-        }
-
-        return NULL;
-}
-
-DIR* safe_closedir(DIR *d) {
-
-        if (d) {
-                PROTECT_ERRNO;
-
-                assert_se(closedir(d) >= 0 || errno != EBADF);
-        }
-
-        return NULL;
-}
-
-int fd_nonblock(int fd, bool nonblock) {
-        int flags, nflags;
-
-        assert(fd >= 0);
-
-        flags = fcntl(fd, F_GETFL, 0);
-        if (flags < 0)
-                return -errno;
-
-        if (nonblock)
-                nflags = flags | O_NONBLOCK;
-        else
-                nflags = flags & ~O_NONBLOCK;
-
-        if (nflags == flags)
-                return 0;
-
-        if (fcntl(fd, F_SETFL, nflags) < 0)
-                return -errno;
-
-        return 0;
-}
-
-int fd_cloexec(int fd, bool cloexec) {
-        int flags, nflags;
-
-        assert(fd >= 0);
-
-        flags = fcntl(fd, F_GETFD, 0);
-        if (flags < 0)
-                return -errno;
-
-        if (cloexec)
-                nflags = flags | FD_CLOEXEC;
-        else
-                nflags = flags & ~FD_CLOEXEC;
-
-        if (nflags == flags)
-                return 0;
-
-        if (fcntl(fd, F_SETFD, nflags) < 0)
-                return -errno;
-
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-_pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) {
-        size_t i;
-
-        assert(n_fdset == 0 || fdset);
-
-        for (i = 0; i < n_fdset; i++)
-                if (fdset[i] == fd)
-                        return true;
-
-        return false;
-}
-
-int close_all_fds(const int except[], size_t n_except) {
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-        int r = 0;
-
-        assert(n_except == 0 || except);
-
-        d = opendir("/proc/self/fd");
-        if (!d) {
-                struct rlimit rl;
-                int fd, max_fd;
-
-                /* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd
-                 * table */
-
-                assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
-
-                if (rl.rlim_max == 0)
-                        return -EINVAL;
-
-                /* Let's take special care if the resource limit is set to unlimited, or actually larger than the range
-                 * of 'int'. Let's avoid implicit overflows. */
-                max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1);
-
-                for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
-                        int q;
-
-                        if (fd_in_set(fd, except, n_except))
-                                continue;
-
-                        q = close_nointr(fd);
-                        if (q < 0 && q != -EBADF && r >= 0)
-                                r = q;
-                }
-
-                return r;
-        }
-
-        FOREACH_DIRENT(de, d, return -errno) {
-                int fd = -1, q;
-
-                if (safe_atoi(de->d_name, &fd) < 0)
-                        /* Let's better ignore this, just in case */
-                        continue;
-
-                if (fd < 3)
-                        continue;
-
-                if (fd == dirfd(d))
-                        continue;
-
-                if (fd_in_set(fd, except, n_except))
-                        continue;
-
-                q = close_nointr(fd);
-                if (q < 0 && q != -EBADF && r >= 0) /* Valgrind has its own FD and doesn't want to have it closed */
-                        r = q;
-        }
-
-        return r;
-}
-
-int same_fd(int a, int b) {
-        struct stat sta, stb;
-        pid_t pid;
-        int r, fa, fb;
-
-        assert(a >= 0);
-        assert(b >= 0);
-
-        /* Compares two file descriptors. Note that semantics are
-         * quite different depending on whether we have kcmp() or we
-         * don't. If we have kcmp() this will only return true for
-         * dup()ed file descriptors, but not otherwise. If we don't
-         * have kcmp() this will also return true for two fds of the same
-         * file, created by separate open() calls. Since we use this
-         * call mostly for filtering out duplicates in the fd store
-         * this difference hopefully doesn't matter too much. */
-
-        if (a == b)
-                return true;
-
-        /* Try to use kcmp() if we have it. */
-        pid = getpid_cached();
-        r = kcmp(pid, pid, KCMP_FILE, a, b);
-        if (r == 0)
-                return true;
-        if (r > 0)
-                return false;
-        if (errno != ENOSYS)
-                return -errno;
-
-        /* We don't have kcmp(), use fstat() instead. */
-        if (fstat(a, &sta) < 0)
-                return -errno;
-
-        if (fstat(b, &stb) < 0)
-                return -errno;
-
-        if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
-                return false;
-
-        /* We consider all device fds different, since two device fds
-         * might refer to quite different device contexts even though
-         * they share the same inode and backing dev_t. */
-
-        if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
-                return false;
-
-        if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
-                return false;
-
-        /* The fds refer to the same inode on disk, let's also check
-         * if they have the same fd flags. This is useful to
-         * distinguish the read and write side of a pipe created with
-         * pipe(). */
-        fa = fcntl(a, F_GETFL);
-        if (fa < 0)
-                return -errno;
-
-        fb = fcntl(b, F_GETFL);
-        if (fb < 0)
-                return -errno;
-
-        return fa == fb;
-}
-#endif /* NM_IGNORED */
-
-void cmsg_close_all(struct msghdr *mh) {
-        struct cmsghdr *cmsg;
-
-        assert(mh);
-
-        CMSG_FOREACH(cmsg, mh)
-                if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
-                        close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
-}
-
-bool fdname_is_valid(const char *s) {
-        const char *p;
-
-        /* Validates a name for $LISTEN_FDNAMES. We basically allow
-         * everything ASCII that's not a control character. Also, as
-         * special exception the ":" character is not allowed, as we
-         * use that as field separator in $LISTEN_FDNAMES.
-         *
-         * Note that the empty string is explicitly allowed
-         * here. However, we limit the length of the names to 255
-         * characters. */
-
-        if (!s)
-                return false;
-
-        for (p = s; *p; p++) {
-                if (*p < ' ')
-                        return false;
-                if (*p >= 127)
-                        return false;
-                if (*p == ':')
-                        return false;
-        }
-
-        return p - s < 256;
-}
-
-int fd_get_path(int fd, char **ret) {
-        _cleanup_close_ int dir = -1;
-        char fdname[DECIMAL_STR_MAX(int)];
-        int r;
-
-        dir = open("/proc/self/fd/", O_CLOEXEC | O_DIRECTORY | O_PATH);
-        if (dir < 0)
-                /* /proc is not available or not set up properly, we're most likely
-                 * in some chroot environment. */
-                return errno == ENOENT ? -EOPNOTSUPP : -errno;
-
-        xsprintf(fdname, "%i", fd);
-
-        r = readlinkat_malloc(dir, fdname, ret);
-        if (r == -ENOENT)
-                /* If the file doesn't exist the fd is invalid */
-                return -EBADF;
-
-        return r;
-}
-
-#if 0 /* NM_IGNORED */
-int move_fd(int from, int to, int cloexec) {
-        int r;
-
-        /* Move fd 'from' to 'to', make sure FD_CLOEXEC remains equal if requested, and release the old fd. If
-         * 'cloexec' is passed as -1, the original FD_CLOEXEC is inherited for the new fd. If it is 0, it is turned
-         * off, if it is > 0 it is turned on. */
-
-        if (from < 0)
-                return -EBADF;
-        if (to < 0)
-                return -EBADF;
-
-        if (from == to) {
-
-                if (cloexec >= 0) {
-                        r = fd_cloexec(to, cloexec);
-                        if (r < 0)
-                                return r;
-                }
-
-                return to;
-        }
-
-        if (cloexec < 0) {
-                int fl;
-
-                fl = fcntl(from, F_GETFD, 0);
-                if (fl < 0)
-                        return -errno;
-
-                cloexec = !!(fl & FD_CLOEXEC);
-        }
-
-        r = dup3(from, to, cloexec ? O_CLOEXEC : 0);
-        if (r < 0)
-                return -errno;
-
-        assert(r == to);
-
-        safe_close(from);
-
-        return to;
-}
-
-int acquire_data_fd(const void *data, size_t size, unsigned flags) {
-
-        _cleanup_close_pair_ int pipefds[2] = { -1, -1 };
-        char pattern[] = "/dev/shm/data-fd-XXXXXX";
-        _cleanup_close_ int fd = -1;
-        int isz = 0, r;
-        ssize_t n;
-        off_t f;
-
-        assert(data || size == 0);
-
-        /* Acquire a read-only file descriptor that when read from returns the specified data. This is much more
-         * complex than I wish it was. But here's why:
-         *
-         * a) First we try to use memfds. They are the best option, as we can seal them nicely to make them
-         *    read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14.
-         *
-         * b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining
-         *    a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged
-         *    clients can only bump their size to a system-wide limit, which might be quite low.
-         *
-         * c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from
-         *    earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via
-         *    /proc/self/<fd>. Unfortunately O_TMPFILE is not available on older kernels on tmpfs.
-         *
-         * d) Finally, we try creating a regular file in /dev/shm, which we then delete.
-         *
-         * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I
-         * figure. */
-
-        if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) {
-                /* As a special case, return /dev/null if we have been called for an empty data block */
-                r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (r < 0)
-                        return -errno;
-
-                return r;
-        }
-
-        if ((flags & ACQUIRE_NO_MEMFD) == 0) {
-                fd = memfd_new("data-fd");
-                if (fd < 0)
-                        goto try_pipe;
-
-                n = write(fd, data, size);
-                if (n < 0)
-                        return -errno;
-                if ((size_t) n != size)
-                        return -EIO;
-
-                f = lseek(fd, 0, SEEK_SET);
-                if (f != 0)
-                        return -errno;
-
-                r = memfd_set_sealed(fd);
-                if (r < 0)
-                        return r;
-
-                return TAKE_FD(fd);
-        }
-
-try_pipe:
-        if ((flags & ACQUIRE_NO_PIPE) == 0) {
-                if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
-                        return -errno;
-
-                isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
-                if (isz < 0)
-                        return -errno;
-
-                if ((size_t) isz < size) {
-                        isz = (int) size;
-                        if (isz < 0 || (size_t) isz != size)
-                                return -E2BIG;
-
-                        /* Try to bump the pipe size */
-                        (void) fcntl(pipefds[1], F_SETPIPE_SZ, isz);
-
-                        /* See if that worked */
-                        isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
-                        if (isz < 0)
-                                return -errno;
-
-                        if ((size_t) isz < size)
-                                goto try_dev_shm;
-                }
-
-                n = write(pipefds[1], data, size);
-                if (n < 0)
-                        return -errno;
-                if ((size_t) n != size)
-                        return -EIO;
-
-                (void) fd_nonblock(pipefds[0], false);
-
-                return TAKE_FD(pipefds[0]);
-        }
-
-try_dev_shm:
-        if ((flags & ACQUIRE_NO_TMPFILE) == 0) {
-                fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500);
-                if (fd < 0)
-                        goto try_dev_shm_without_o_tmpfile;
-
-                n = write(fd, data, size);
-                if (n < 0)
-                        return -errno;
-                if ((size_t) n != size)
-                        return -EIO;
-
-                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
-                return fd_reopen(fd, O_RDONLY|O_CLOEXEC);
-        }
-
-try_dev_shm_without_o_tmpfile:
-        if ((flags & ACQUIRE_NO_REGULAR) == 0) {
-                fd = mkostemp_safe(pattern);
-                if (fd < 0)
-                        return fd;
-
-                n = write(fd, data, size);
-                if (n < 0) {
-                        r = -errno;
-                        goto unlink_and_return;
-                }
-                if ((size_t) n != size) {
-                        r = -EIO;
-                        goto unlink_and_return;
-                }
-
-                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
-                r = open(pattern, O_RDONLY|O_CLOEXEC);
-                if (r < 0)
-                        r = -errno;
-
-        unlink_and_return:
-                (void) unlink(pattern);
-                return r;
-        }
-
-        return -EOPNOTSUPP;
-}
-
-/* When the data is smaller or equal to 64K, try to place the copy in a memfd/pipe */
-#define DATA_FD_MEMORY_LIMIT (64U*1024U)
-
-/* If memfd/pipe didn't work out, then let's use a file in /tmp up to a size of 1M. If it's large than that use /var/tmp instead. */
-#define DATA_FD_TMP_LIMIT (1024U*1024U)
-
-int fd_duplicate_data_fd(int fd) {
-
-        _cleanup_close_ int copy_fd = -1, tmp_fd = -1;
-        _cleanup_free_ void *remains = NULL;
-        size_t remains_size = 0;
-        const char *td;
-        struct stat st;
-        int r;
-
-        /* Creates a 'data' fd from the specified source fd, containing all the same data in a read-only fashion, but
-         * independent of it (i.e. the source fd can be closed and unmounted after this call succeeded). Tries to be
-         * somewhat smart about where to place the data. In the best case uses a memfd(). If memfd() are not supported
-         * uses a pipe instead. For larger data will use an unlinked file in /tmp, and for even larger data one in
-         * /var/tmp. */
-
-        if (fstat(fd, &st) < 0)
-                return -errno;
-
-        /* For now, let's only accept regular files, sockets, pipes and char devices */
-        if (S_ISDIR(st.st_mode))
-                return -EISDIR;
-        if (S_ISLNK(st.st_mode))
-                return -ELOOP;
-        if (!S_ISREG(st.st_mode) && !S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode) && !S_ISCHR(st.st_mode))
-                return -EBADFD;
-
-        /* If we have reason to believe the data is bounded in size, then let's use memfds or pipes as backing fd. Note
-         * that we use the reported regular file size only as a hint, given that there are plenty special files in
-         * /proc and /sys which report a zero file size but can be read from. */
-
-        if (!S_ISREG(st.st_mode) || st.st_size < DATA_FD_MEMORY_LIMIT) {
-
-                /* Try a memfd first */
-                copy_fd = memfd_new("data-fd");
-                if (copy_fd >= 0) {
-                        off_t f;
-
-                        r = copy_bytes(fd, copy_fd, DATA_FD_MEMORY_LIMIT, 0);
-                        if (r < 0)
-                                return r;
-
-                        f = lseek(copy_fd, 0, SEEK_SET);
-                        if (f != 0)
-                                return -errno;
-
-                        if (r == 0) {
-                                /* Did it fit into the limit? If so, we are done. */
-                                r = memfd_set_sealed(copy_fd);
-                                if (r < 0)
-                                        return r;
-
-                                return TAKE_FD(copy_fd);
-                        }
-
-                        /* Hmm, pity, this didn't fit. Let's fall back to /tmp then, see below */
-
-                } else {
-                        _cleanup_(close_pairp) int pipefds[2] = { -1, -1 };
-                        int isz;
-
-                        /* If memfds aren't available, use a pipe. Set O_NONBLOCK so that we will get EAGAIN rather
-                         * then block indefinitely when we hit the pipe size limit */
-
-                        if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
-                                return -errno;
-
-                        isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
-                        if (isz < 0)
-                                return -errno;
-
-                        /* Try to enlarge the pipe size if necessary */
-                        if ((size_t) isz < DATA_FD_MEMORY_LIMIT) {
-
-                                (void) fcntl(pipefds[1], F_SETPIPE_SZ, DATA_FD_MEMORY_LIMIT);
-
-                                isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
-                                if (isz < 0)
-                                        return -errno;
-                        }
-
-                        if ((size_t) isz >= DATA_FD_MEMORY_LIMIT) {
-
-                                r = copy_bytes_full(fd, pipefds[1], DATA_FD_MEMORY_LIMIT, 0, &remains, &remains_size);
-                                if (r < 0 && r != -EAGAIN)
-                                        return r; /* If we get EAGAIN it could be because of the source or because of
-                                                   * the destination fd, we can't know, as sendfile() and friends won't
-                                                   * tell us. Hence, treat this as reason to fall back, just to be
-                                                   * sure. */
-                                if (r == 0) {
-                                        /* Everything fit in, yay! */
-                                        (void) fd_nonblock(pipefds[0], false);
-
-                                        return TAKE_FD(pipefds[0]);
-                                }
-
-                                /* Things didn't fit in. But we read data into the pipe, let's remember that, so that
-                                 * when writing the new file we incorporate this first. */
-                                copy_fd = TAKE_FD(pipefds[0]);
-                        }
-                }
-        }
-
-        /* If we have reason to believe this will fit fine in /tmp, then use that as first fallback. */
-        if ((!S_ISREG(st.st_mode) || st.st_size < DATA_FD_TMP_LIMIT) &&
-            (DATA_FD_MEMORY_LIMIT + remains_size) < DATA_FD_TMP_LIMIT) {
-                off_t f;
-
-                tmp_fd = open_tmpfile_unlinkable(NULL /* NULL as directory means /tmp */, O_RDWR|O_CLOEXEC);
-                if (tmp_fd < 0)
-                        return tmp_fd;
-
-                if (copy_fd >= 0) {
-                        /* If we tried a memfd/pipe first and it ended up being too large, then copy this into the
-                         * temporary file first. */
-
-                        r = copy_bytes(copy_fd, tmp_fd, UINT64_MAX, 0);
-                        if (r < 0)
-                                return r;
-
-                        assert(r == 0);
-                }
-
-                if (remains_size > 0) {
-                        /* If there were remaining bytes (i.e. read into memory, but not written out yet) from the
-                         * failed copy operation, let's flush them out next. */
-
-                        r = loop_write(tmp_fd, remains, remains_size, false);
-                        if (r < 0)
-                                return r;
-                }
-
-                r = copy_bytes(fd, tmp_fd, DATA_FD_TMP_LIMIT - DATA_FD_MEMORY_LIMIT - remains_size, COPY_REFLINK);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        goto finish;  /* Yay, it fit in */
-
-                /* It didn't fit in. Let's not forget to use what we already used */
-                f = lseek(tmp_fd, 0, SEEK_SET);
-                if (f != 0)
-                        return -errno;
-
-                safe_close(copy_fd);
-                copy_fd = TAKE_FD(tmp_fd);
-
-                remains = mfree(remains);
-                remains_size = 0;
-        }
-
-        /* As last fallback use /var/tmp */
-        r = var_tmp_dir(&td);
-        if (r < 0)
-                return r;
-
-        tmp_fd = open_tmpfile_unlinkable(td, O_RDWR|O_CLOEXEC);
-        if (tmp_fd < 0)
-                return tmp_fd;
-
-        if (copy_fd >= 0) {
-                /* If we tried a memfd/pipe first, or a file in /tmp, and it ended up being too large, than copy this
-                 * into the temporary file first. */
-                r = copy_bytes(copy_fd, tmp_fd, UINT64_MAX, COPY_REFLINK);
-                if (r < 0)
-                        return r;
-
-                assert(r == 0);
-        }
-
-        if (remains_size > 0) {
-                /* Then, copy in any read but not yet written bytes. */
-                r = loop_write(tmp_fd, remains, remains_size, false);
-                if (r < 0)
-                        return r;
-        }
-
-        /* Copy in the rest */
-        r = copy_bytes(fd, tmp_fd, UINT64_MAX, COPY_REFLINK);
-        if (r < 0)
-                return r;
-
-        assert(r == 0);
-
-finish:
-        /* Now convert the O_RDWR file descriptor into an O_RDONLY one (and as side effect seek to the beginning of the
-         * file again */
-
-        return fd_reopen(tmp_fd, O_RDONLY|O_CLOEXEC);
-}
-#endif /* NM_IGNORED */
-
-int fd_move_above_stdio(int fd) {
-        int flags, copy;
-        PROTECT_ERRNO;
-
-        /* Moves the specified file descriptor if possible out of the range [0…2], i.e. the range of
-         * stdin/stdout/stderr. If it can't be moved outside of this range the original file descriptor is
-         * returned. This call is supposed to be used for long-lasting file descriptors we allocate in our code that
-         * might get loaded into foreign code, and where we want ensure our fds are unlikely used accidentally as
-         * stdin/stdout/stderr of unrelated code.
-         *
-         * Note that this doesn't fix any real bugs, it just makes it less likely that our code will be affected by
-         * buggy code from others that mindlessly invokes 'fprintf(stderr, …' or similar in places where stderr has
-         * been closed before.
-         *
-         * This function is written in a "best-effort" and "least-impact" style. This means whenever we encounter an
-         * error we simply return the original file descriptor, and we do not touch errno. */
-
-        if (fd < 0 || fd > 2)
-                return fd;
-
-        flags = fcntl(fd, F_GETFD, 0);
-        if (flags < 0)
-                return fd;
-
-        if (flags & FD_CLOEXEC)
-                copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
-        else
-                copy = fcntl(fd, F_DUPFD, 3);
-        if (copy < 0)
-                return fd;
-
-        assert(copy > 2);
-
-        (void) close(fd);
-        return copy;
-}
-
-#if 0 /* NM_IGNORED */
-int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd) {
-
-        int fd[3] = { /* Put together an array of fds we work on */
-                original_input_fd,
-                original_output_fd,
-                original_error_fd
-        };
-
-        int r, i,
-                null_fd = -1,                /* if we open /dev/null, we store the fd to it here */
-                copy_fd[3] = { -1, -1, -1 }; /* This contains all fds we duplicate here temporarily, and hence need to close at the end */
-        bool null_readable, null_writable;
-
-        /* Sets up stdin, stdout, stderr with the three file descriptors passed in. If any of the descriptors is
-         * specified as -1 it will be connected with /dev/null instead. If any of the file descriptors is passed as
-         * itself (e.g. stdin as STDIN_FILENO) it is left unmodified, but the O_CLOEXEC bit is turned off should it be
-         * on.
-         *
-         * Note that if any of the passed file descriptors are > 2 they will be closed — both on success and on
-         * failure! Thus, callers should assume that when this function returns the input fds are invalidated.
-         *
-         * Note that when this function fails stdin/stdout/stderr might remain half set up!
-         *
-         * O_CLOEXEC is turned off for all three file descriptors (which is how it should be for
-         * stdin/stdout/stderr). */
-
-        null_readable = original_input_fd < 0;
-        null_writable = original_output_fd < 0 || original_error_fd < 0;
-
-        /* First step, open /dev/null once, if we need it */
-        if (null_readable || null_writable) {
-
-                /* Let's open this with O_CLOEXEC first, and convert it to non-O_CLOEXEC when we move the fd to the final position. */
-                null_fd = open("/dev/null", (null_readable && null_writable ? O_RDWR :
-                                             null_readable ? O_RDONLY : O_WRONLY) | O_CLOEXEC);
-                if (null_fd < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
-                /* If this fd is in the 0…2 range, let's move it out of it */
-                if (null_fd < 3) {
-                        int copy;
-
-                        copy = fcntl(null_fd, F_DUPFD_CLOEXEC, 3); /* Duplicate this with O_CLOEXEC set */
-                        if (copy < 0) {
-                                r = -errno;
-                                goto finish;
-                        }
-
-                        safe_close(null_fd);
-                        null_fd = copy;
-                }
-        }
-
-        /* Let's assemble fd[] with the fds to install in place of stdin/stdout/stderr */
-        for (i = 0; i < 3; i++) {
-
-                if (fd[i] < 0)
-                        fd[i] = null_fd;        /* A negative parameter means: connect this one to /dev/null */
-                else if (fd[i] != i && fd[i] < 3) {
-                        /* This fd is in the 0…2 territory, but not at its intended place, move it out of there, so that we can work there. */
-                        copy_fd[i] = fcntl(fd[i], F_DUPFD_CLOEXEC, 3); /* Duplicate this with O_CLOEXEC set */
-                        if (copy_fd[i] < 0) {
-                                r = -errno;
-                                goto finish;
-                        }
-
-                        fd[i] = copy_fd[i];
-                }
-        }
-
-        /* At this point we now have the fds to use in fd[], and they are all above the stdio range, so that we
-         * have freedom to move them around. If the fds already were at the right places then the specific fds are
-         * -1. Let's now move them to the right places. This is the point of no return. */
-        for (i = 0; i < 3; i++) {
-
-                if (fd[i] == i) {
-
-                        /* fd is already in place, but let's make sure O_CLOEXEC is off */
-                        r = fd_cloexec(i, false);
-                        if (r < 0)
-                                goto finish;
-
-                } else {
-                        assert(fd[i] > 2);
-
-                        if (dup2(fd[i], i) < 0) { /* Turns off O_CLOEXEC on the new fd. */
-                                r = -errno;
-                                goto finish;
-                        }
-                }
-        }
-
-        r = 0;
-
-finish:
-        /* Close the original fds, but only if they were outside of the stdio range. Also, properly check for the same
-         * fd passed in multiple times. */
-        safe_close_above_stdio(original_input_fd);
-        if (original_output_fd != original_input_fd)
-                safe_close_above_stdio(original_output_fd);
-        if (original_error_fd != original_input_fd && original_error_fd != original_output_fd)
-                safe_close_above_stdio(original_error_fd);
-
-        /* Close the copies we moved > 2 */
-        for (i = 0; i < 3; i++)
-                safe_close(copy_fd[i]);
-
-        /* Close our null fd, if it's > 2 */
-        safe_close_above_stdio(null_fd);
-
-        return r;
-}
-
-int fd_reopen(int fd, int flags) {
-        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
-        int new_fd;
-
-        /* Reopens the specified fd with new flags. This is useful for convert an O_PATH fd into a regular one, or to
-         * turn O_RDWR fds into O_RDONLY fds.
-         *
-         * This doesn't work on sockets (since they cannot be open()ed, ever).
-         *
-         * This implicitly resets the file read index to 0. */
-
-        xsprintf(procfs_path, "/proc/self/fd/%i", fd);
-        new_fd = open(procfs_path, flags);
-        if (new_fd < 0)
-                return -errno;
-
-        return new_fd;
-}
-
-int read_nr_open(void) {
-        _cleanup_free_ char *nr_open = NULL;
-        int r;
-
-        /* Returns the kernel's current fd limit, either by reading it of /proc/sys if that works, or using the
-         * hard-coded default compiled-in value of current kernels (1M) if not. This call will never fail. */
-
-        r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
-        if (r < 0)
-                log_debug_errno(r, "Failed to read /proc/sys/fs/nr_open, ignoring: %m");
-        else {
-                int v;
-
-                r = safe_atoi(nr_open, &v);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to parse /proc/sys/fs/nr_open value '%s', ignoring: %m", nr_open);
-                else
-                        return v;
-        }
-
-        /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
-        return 1024 * 1024;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/fd-util.h b/src/systemd/src/basic/fd-util.h
deleted file mode 100644
index 00303a7e..00000000
--- a/src/systemd/src/basic/fd-util.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <dirent.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <sys/socket.h>
-
-#include "macro.h"
-
-/* Make sure we can distinguish fd 0 and NULL */
-#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1)
-#define PTR_TO_FD(p) (PTR_TO_INT(p)-1)
-
-int close_nointr(int fd);
-int safe_close(int fd);
-void safe_close_pair(int p[]);
-
-static inline int safe_close_above_stdio(int fd) {
-        if (fd < 3) /* Don't close stdin/stdout/stderr, but still invalidate the fd by returning -1 */
-                return -1;
-
-        return safe_close(fd);
-}
-
-void close_many(const int fds[], size_t n_fd);
-
-int fclose_nointr(FILE *f);
-FILE* safe_fclose(FILE *f);
-DIR* safe_closedir(DIR *f);
-
-static inline void closep(int *fd) {
-        safe_close(*fd);
-}
-
-static inline void close_pairp(int (*p)[2]) {
-        safe_close_pair(*p);
-}
-
-static inline void fclosep(FILE **f) {
-        safe_fclose(*f);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose);
-DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir);
-
-#define _cleanup_close_ _cleanup_(closep)
-#define _cleanup_fclose_ _cleanup_(fclosep)
-#define _cleanup_pclose_ _cleanup_(pclosep)
-#define _cleanup_closedir_ _cleanup_(closedirp)
-#define _cleanup_close_pair_ _cleanup_(close_pairp)
-
-int fd_nonblock(int fd, bool nonblock);
-int fd_cloexec(int fd, bool cloexec);
-
-int close_all_fds(const int except[], size_t n_except);
-
-int same_fd(int a, int b);
-
-void cmsg_close_all(struct msghdr *mh);
-
-bool fdname_is_valid(const char *s);
-
-int fd_get_path(int fd, char **ret);
-
-int move_fd(int from, int to, int cloexec);
-
-enum {
-        ACQUIRE_NO_DEV_NULL = 1 << 0,
-        ACQUIRE_NO_MEMFD    = 1 << 1,
-        ACQUIRE_NO_PIPE     = 1 << 2,
-        ACQUIRE_NO_TMPFILE  = 1 << 3,
-        ACQUIRE_NO_REGULAR  = 1 << 4,
-};
-
-int acquire_data_fd(const void *data, size_t size, unsigned flags);
-
-int fd_duplicate_data_fd(int fd);
-
-/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
-/* The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.
- * See the icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
-#define ERRNO_IS_DISCONNECT(r)                                          \
-        IN_SET(r,                                                       \
-               ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \
-               ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, ENONET)
-
-/* Resource exhaustion, could be our fault or general system trouble */
-#define ERRNO_IS_RESOURCE(r) \
-        IN_SET(r, ENOMEM, EMFILE, ENFILE)
-
-int fd_move_above_stdio(int fd);
-
-int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd);
-
-static inline int make_null_stdio(void) {
-        return rearrange_stdio(-1, -1, -1);
-}
-
-/* Like TAKE_PTR() but for file descriptors, resetting them to -1 */
-#define TAKE_FD(fd)                             \
-        ({                                      \
-                int _fd_ = (fd);                \
-                (fd) = -1;                      \
-                _fd_;                           \
-        })
-
-int fd_reopen(int fd, int flags);
-
-int read_nr_open(void);
diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c
deleted file mode 100644
index 3978c3a7..00000000
--- a/src/systemd/src/basic/fileio.c
+++ /dev/null
@@ -1,1671 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio_ext.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "ctype.h"
-#include "def.h"
-#include "env-util.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "hexdecoct.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "random-util.h"
-#include "stdio-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-#include "umask-util.h"
-#include "utf8.h"
-
-#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
-
-#if 0 /* NM_IGNORED */
-int write_string_stream_ts(
-                FILE *f,
-                const char *line,
-                WriteStringFileFlags flags,
-                struct timespec *ts) {
-
-        bool needs_nl;
-        int r;
-
-        assert(f);
-        assert(line);
-
-        if (ferror(f))
-                return -EIO;
-
-        needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
-
-        if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
-                /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
-                 * that the write goes out in one go, instead of two */
-
-                line = strjoina(line, "\n");
-                needs_nl = false;
-        }
-
-        if (fputs(line, f) == EOF)
-                return -errno;
-
-        if (needs_nl)
-                if (fputc('\n', f) == EOF)
-                        return -errno;
-
-        if (flags & WRITE_STRING_FILE_SYNC)
-                r = fflush_sync_and_check(f);
-        else
-                r = fflush_and_check(f);
-        if (r < 0)
-                return r;
-
-        if (ts) {
-                struct timespec twice[2] = {*ts, *ts};
-
-                if (futimens(fileno(f), twice) < 0)
-                        return -errno;
-        }
-
-        return 0;
-}
-
-static int write_string_file_atomic(
-                const char *fn,
-                const char *line,
-                WriteStringFileFlags flags,
-                struct timespec *ts) {
-
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
-        int r;
-
-        assert(fn);
-        assert(line);
-
-        r = fopen_temporary(fn, &f, &p);
-        if (r < 0)
-                return r;
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-        (void) fchmod_umask(fileno(f), 0644);
-
-        r = write_string_stream_ts(f, line, flags, ts);
-        if (r < 0)
-                goto fail;
-
-        if (rename(p, fn) < 0) {
-                r = -errno;
-                goto fail;
-        }
-
-        return 0;
-
-fail:
-        (void) unlink(p);
-        return r;
-}
-
-int write_string_file_ts(
-                const char *fn,
-                const char *line,
-                WriteStringFileFlags flags,
-                struct timespec *ts) {
-
-        _cleanup_fclose_ FILE *f = NULL;
-        int q, r;
-
-        assert(fn);
-        assert(line);
-
-        /* We don't know how to verify whether the file contents was already on-disk. */
-        assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC)));
-
-        if (flags & WRITE_STRING_FILE_ATOMIC) {
-                assert(flags & WRITE_STRING_FILE_CREATE);
-
-                r = write_string_file_atomic(fn, line, flags, ts);
-                if (r < 0)
-                        goto fail;
-
-                return r;
-        } else
-                assert(!ts);
-
-        if (flags & WRITE_STRING_FILE_CREATE) {
-                f = fopen(fn, "we");
-                if (!f) {
-                        r = -errno;
-                        goto fail;
-                }
-        } else {
-                int fd;
-
-                /* We manually build our own version of fopen(..., "we") that
-                 * works without O_CREAT */
-                fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0) {
-                        r = -errno;
-                        goto fail;
-                }
-
-                f = fdopen(fd, "we");
-                if (!f) {
-                        r = -errno;
-                        safe_close(fd);
-                        goto fail;
-                }
-        }
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
-                setvbuf(f, NULL, _IONBF, 0);
-
-        r = write_string_stream_ts(f, line, flags, ts);
-        if (r < 0)
-                goto fail;
-
-        return 0;
-
-fail:
-        if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
-                return r;
-
-        f = safe_fclose(f);
-
-        /* OK, the operation failed, but let's see if the right
-         * contents in place already. If so, eat up the error. */
-
-        q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
-        if (q <= 0)
-                return r;
-
-        return 0;
-}
-
-int write_string_filef(
-                const char *fn,
-                WriteStringFileFlags flags,
-                const char *format, ...) {
-
-        _cleanup_free_ char *p = NULL;
-        va_list ap;
-        int r;
-
-        va_start(ap, format);
-        r = vasprintf(&p, format, ap);
-        va_end(ap);
-
-        if (r < 0)
-                return -ENOMEM;
-
-        return write_string_file(fn, p, flags);
-}
-
-int read_one_line_file(const char *fn, char **line) {
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
-        assert(fn);
-        assert(line);
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        r = read_line(f, LONG_LINE_MAX, line);
-        return r < 0 ? r : 0;
-}
-
-int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *buf = NULL;
-        size_t l, k;
-
-        assert(fn);
-        assert(blob);
-
-        l = strlen(blob);
-
-        if (accept_extra_nl && endswith(blob, "\n"))
-                accept_extra_nl = false;
-
-        buf = malloc(l + accept_extra_nl + 1);
-        if (!buf)
-                return -ENOMEM;
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        /* We try to read one byte more than we need, so that we know whether we hit eof */
-        errno = 0;
-        k = fread(buf, 1, l + accept_extra_nl + 1, f);
-        if (ferror(f))
-                return errno > 0 ? -errno : -EIO;
-
-        if (k != l && k != l + accept_extra_nl)
-                return 0;
-        if (memcmp(buf, blob, l) != 0)
-                return 0;
-        if (k > l && buf[l] != '\n')
-                return 0;
-
-        return 1;
-}
-#endif /* NM_IGNORED */
-
-int read_full_stream(FILE *f, char **contents, size_t *size) {
-        _cleanup_free_ char *buf = NULL;
-        struct stat st;
-        size_t n, l;
-        int fd;
-
-        assert(f);
-        assert(contents);
-
-        n = LINE_MAX;
-
-        fd = fileno(f);
-        if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's
-                        * optimize our buffering) */
-
-                if (fstat(fileno(f), &st) < 0)
-                        return -errno;
-
-                if (S_ISREG(st.st_mode)) {
-
-                        /* Safety check */
-                        if (st.st_size > READ_FULL_BYTES_MAX)
-                                return -E2BIG;
-
-                        /* Start with the right file size, but be prepared for files from /proc which generally report a file
-                         * size of 0. Note that we increase the size to read here by one, so that the first read attempt
-                         * already makes us notice the EOF. */
-                        if (st.st_size > 0)
-                                n = st.st_size + 1;
-                }
-        }
-
-        l = 0;
-        for (;;) {
-                char *t;
-                size_t k;
-
-                t = realloc(buf, n + 1);
-                if (!t)
-                        return -ENOMEM;
-
-                buf = t;
-                errno = 0;
-                k = fread(buf + l, 1, n - l, f);
-                if (k > 0)
-                        l += k;
-
-                if (ferror(f))
-                        return errno > 0 ? -errno : -EIO;
-
-                if (feof(f))
-                        break;
-
-                /* We aren't expecting fread() to return a short read outside
-                 * of (error && eof), assert buffer is full and enlarge buffer.
-                 */
-                assert(l == n);
-
-                /* Safety check */
-                if (n >= READ_FULL_BYTES_MAX)
-                        return -E2BIG;
-
-                n = MIN(n * 2, READ_FULL_BYTES_MAX);
-        }
-
-        buf[l] = 0;
-        *contents = TAKE_PTR(buf);
-
-        if (size)
-                *size = l;
-
-        return 0;
-}
-
-int read_full_file(const char *fn, char **contents, size_t *size) {
-        _cleanup_fclose_ FILE *f = NULL;
-
-        assert(fn);
-        assert(contents);
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        return read_full_stream(f, contents, size);
-}
-
-static int parse_env_file_internal(
-                FILE *f,
-                const char *fname,
-                const char *newline,
-                int (*push) (const char *filename, unsigned line,
-                             const char *key, char *value, void *userdata, int *n_pushed),
-                void *userdata,
-                int *n_pushed) {
-
-        size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
-        _cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
-        unsigned line = 1;
-        char *p;
-        int r;
-
-        enum {
-                PRE_KEY,
-                KEY,
-                PRE_VALUE,
-                VALUE,
-                VALUE_ESCAPE,
-                SINGLE_QUOTE_VALUE,
-                SINGLE_QUOTE_VALUE_ESCAPE,
-                DOUBLE_QUOTE_VALUE,
-                DOUBLE_QUOTE_VALUE_ESCAPE,
-                COMMENT,
-                COMMENT_ESCAPE
-        } state = PRE_KEY;
-
-        assert(newline);
-
-        if (f)
-                r = read_full_stream(f, &contents, NULL);
-        else
-                r = read_full_file(fname, &contents, NULL);
-        if (r < 0)
-                return r;
-
-        for (p = contents; *p; p++) {
-                char c = *p;
-
-                switch (state) {
-
-                case PRE_KEY:
-                        if (strchr(COMMENTS, c))
-                                state = COMMENT;
-                        else if (!strchr(WHITESPACE, c)) {
-                                state = KEY;
-                                last_key_whitespace = (size_t) -1;
-
-                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
-                                        return -ENOMEM;
-
-                                key[n_key++] = c;
-                        }
-                        break;
-
-                case KEY:
-                        if (strchr(newline, c)) {
-                                state = PRE_KEY;
-                                line++;
-                                n_key = 0;
-                        } else if (c == '=') {
-                                state = PRE_VALUE;
-                                last_value_whitespace = (size_t) -1;
-                        } else {
-                                if (!strchr(WHITESPACE, c))
-                                        last_key_whitespace = (size_t) -1;
-                                else if (last_key_whitespace == (size_t) -1)
-                                         last_key_whitespace = n_key;
-
-                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
-                                        return -ENOMEM;
-
-                                key[n_key++] = c;
-                        }
-
-                        break;
-
-                case PRE_VALUE:
-                        if (strchr(newline, c)) {
-                                state = PRE_KEY;
-                                line++;
-                                key[n_key] = 0;
-
-                                if (value)
-                                        value[n_value] = 0;
-
-                                /* strip trailing whitespace from key */
-                                if (last_key_whitespace != (size_t) -1)
-                                        key[last_key_whitespace] = 0;
-
-                                r = push(fname, line, key, value, userdata, n_pushed);
-                                if (r < 0)
-                                        return r;
-
-                                n_key = 0;
-                                value = NULL;
-                                value_alloc = n_value = 0;
-
-                        } else if (c == '\'')
-                                state = SINGLE_QUOTE_VALUE;
-                        else if (c == '\"')
-                                state = DOUBLE_QUOTE_VALUE;
-                        else if (c == '\\')
-                                state = VALUE_ESCAPE;
-                        else if (!strchr(WHITESPACE, c)) {
-                                state = VALUE;
-
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return  -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-
-                        break;
-
-                case VALUE:
-                        if (strchr(newline, c)) {
-                                state = PRE_KEY;
-                                line++;
-
-                                key[n_key] = 0;
-
-                                if (value)
-                                        value[n_value] = 0;
-
-                                /* Chomp off trailing whitespace from value */
-                                if (last_value_whitespace != (size_t) -1)
-                                        value[last_value_whitespace] = 0;
-
-                                /* strip trailing whitespace from key */
-                                if (last_key_whitespace != (size_t) -1)
-                                        key[last_key_whitespace] = 0;
-
-                                r = push(fname, line, key, value, userdata, n_pushed);
-                                if (r < 0)
-                                        return r;
-
-                                n_key = 0;
-                                value = NULL;
-                                value_alloc = n_value = 0;
-
-                        } else if (c == '\\') {
-                                state = VALUE_ESCAPE;
-                                last_value_whitespace = (size_t) -1;
-                        } else {
-                                if (!strchr(WHITESPACE, c))
-                                        last_value_whitespace = (size_t) -1;
-                                else if (last_value_whitespace == (size_t) -1)
-                                        last_value_whitespace = n_value;
-
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-
-                        break;
-
-                case VALUE_ESCAPE:
-                        state = VALUE;
-
-                        if (!strchr(newline, c)) {
-                                /* Escaped newlines we eat up entirely */
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-                        break;
-
-                case SINGLE_QUOTE_VALUE:
-                        if (c == '\'')
-                                state = PRE_VALUE;
-                        else if (c == '\\')
-                                state = SINGLE_QUOTE_VALUE_ESCAPE;
-                        else {
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-
-                        break;
-
-                case SINGLE_QUOTE_VALUE_ESCAPE:
-                        state = SINGLE_QUOTE_VALUE;
-
-                        if (!strchr(newline, c)) {
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-                        break;
-
-                case DOUBLE_QUOTE_VALUE:
-                        if (c == '\"')
-                                state = PRE_VALUE;
-                        else if (c == '\\')
-                                state = DOUBLE_QUOTE_VALUE_ESCAPE;
-                        else {
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-
-                        break;
-
-                case DOUBLE_QUOTE_VALUE_ESCAPE:
-                        state = DOUBLE_QUOTE_VALUE;
-
-                        if (!strchr(newline, c)) {
-                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
-                                        return -ENOMEM;
-
-                                value[n_value++] = c;
-                        }
-                        break;
-
-                case COMMENT:
-                        if (c == '\\')
-                                state = COMMENT_ESCAPE;
-                        else if (strchr(newline, c)) {
-                                state = PRE_KEY;
-                                line++;
-                        }
-                        break;
-
-                case COMMENT_ESCAPE:
-                        state = COMMENT;
-                        break;
-                }
-        }
-
-        if (IN_SET(state,
-                   PRE_VALUE,
-                   VALUE,
-                   VALUE_ESCAPE,
-                   SINGLE_QUOTE_VALUE,
-                   SINGLE_QUOTE_VALUE_ESCAPE,
-                   DOUBLE_QUOTE_VALUE,
-                   DOUBLE_QUOTE_VALUE_ESCAPE)) {
-
-                key[n_key] = 0;
-
-                if (value)
-                        value[n_value] = 0;
-
-                if (state == VALUE)
-                        if (last_value_whitespace != (size_t) -1)
-                                value[last_value_whitespace] = 0;
-
-                /* strip trailing whitespace from key */
-                if (last_key_whitespace != (size_t) -1)
-                        key[last_key_whitespace] = 0;
-
-                r = push(fname, line, key, value, userdata, n_pushed);
-                if (r < 0)
-                        return r;
-
-                value = NULL;
-        }
-
-        return 0;
-}
-
-static int check_utf8ness_and_warn(
-                const char *filename, unsigned line,
-                const char *key, char *value) {
-
-        if (!utf8_is_valid(key)) {
-                _cleanup_free_ char *p = NULL;
-
-                p = utf8_escape_invalid(key);
-                log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
-                return -EINVAL;
-        }
-
-        if (value && !utf8_is_valid(value)) {
-                _cleanup_free_ char *p = NULL;
-
-                p = utf8_escape_invalid(value);
-                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
-                return -EINVAL;
-        }
-
-        return 0;
-}
-
-static int parse_env_file_push(
-                const char *filename, unsigned line,
-                const char *key, char *value,
-                void *userdata,
-                int *n_pushed) {
-
-        const char *k;
-        va_list aq, *ap = userdata;
-        int r;
-
-        r = check_utf8ness_and_warn(filename, line, key, value);
-        if (r < 0)
-                return r;
-
-        va_copy(aq, *ap);
-
-        while ((k = va_arg(aq, const char *))) {
-                char **v;
-
-                v = va_arg(aq, char **);
-
-                if (streq(key, k)) {
-                        va_end(aq);
-                        free(*v);
-                        *v = value;
-
-                        if (n_pushed)
-                                (*n_pushed)++;
-
-                        return 1;
-                }
-        }
-
-        va_end(aq);
-        free(value);
-
-        return 0;
-}
-
-int parse_env_filev(
-                FILE *f,
-                const char *fname,
-                const char *newline,
-                va_list ap) {
-
-        int r, n_pushed = 0;
-        va_list aq;
-
-        if (!newline)
-                newline = NEWLINE;
-
-        va_copy(aq, ap);
-        r = parse_env_file_internal(f, fname, newline, parse_env_file_push, &aq, &n_pushed);
-        va_end(aq);
-        if (r < 0)
-                return r;
-
-        return n_pushed;
-}
-
-int parse_env_file(
-                FILE *f,
-                const char *fname,
-                const char *newline,
-                ...) {
-
-        va_list ap;
-        int r;
-
-        va_start(ap, newline);
-        r = parse_env_filev(f, fname, newline, ap);
-        va_end(ap);
-
-        return r;
-}
-
-#if 0 /* NM_IGNORED */
-static int load_env_file_push(
-                const char *filename, unsigned line,
-                const char *key, char *value,
-                void *userdata,
-                int *n_pushed) {
-        char ***m = userdata;
-        char *p;
-        int r;
-
-        r = check_utf8ness_and_warn(filename, line, key, value);
-        if (r < 0)
-                return r;
-
-        p = strjoin(key, "=", value);
-        if (!p)
-                return -ENOMEM;
-
-        r = strv_env_replace(m, p);
-        if (r < 0) {
-                free(p);
-                return r;
-        }
-
-        if (n_pushed)
-                (*n_pushed)++;
-
-        free(value);
-        return 0;
-}
-
-int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
-        char **m = NULL;
-        int r;
-
-        if (!newline)
-                newline = NEWLINE;
-
-        r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL);
-        if (r < 0) {
-                strv_free(m);
-                return r;
-        }
-
-        *rl = m;
-        return 0;
-}
-
-static int load_env_file_push_pairs(
-                const char *filename, unsigned line,
-                const char *key, char *value,
-                void *userdata,
-                int *n_pushed) {
-        char ***m = userdata;
-        int r;
-
-        r = check_utf8ness_and_warn(filename, line, key, value);
-        if (r < 0)
-                return r;
-
-        r = strv_extend(m, key);
-        if (r < 0)
-                return -ENOMEM;
-
-        if (!value) {
-                r = strv_extend(m, "");
-                if (r < 0)
-                        return -ENOMEM;
-        } else {
-                r = strv_push(m, value);
-                if (r < 0)
-                        return r;
-        }
-
-        if (n_pushed)
-                (*n_pushed)++;
-
-        return 0;
-}
-
-int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
-        char **m = NULL;
-        int r;
-
-        if (!newline)
-                newline = NEWLINE;
-
-        r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
-        if (r < 0) {
-                strv_free(m);
-                return r;
-        }
-
-        *rl = m;
-        return 0;
-}
-
-static int merge_env_file_push(
-                const char *filename, unsigned line,
-                const char *key, char *value,
-                void *userdata,
-                int *n_pushed) {
-
-        char ***env = userdata;
-        char *expanded_value;
-
-        assert(env);
-
-        if (!value) {
-                log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
-                return 0;
-        }
-
-        if (!env_name_is_valid(key)) {
-                log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
-                free(value);
-                return 0;
-        }
-
-        expanded_value = replace_env(value, *env,
-                                     REPLACE_ENV_USE_ENVIRONMENT|
-                                     REPLACE_ENV_ALLOW_BRACELESS|
-                                     REPLACE_ENV_ALLOW_EXTENDED);
-        if (!expanded_value)
-                return -ENOMEM;
-
-        free_and_replace(value, expanded_value);
-
-        return load_env_file_push(filename, line, key, value, env, n_pushed);
-}
-
-int merge_env_file(
-                char ***env,
-                FILE *f,
-                const char *fname) {
-
-        /* NOTE: this function supports braceful and braceless variable expansions,
-         * plus "extended" substitutions, unlike other exported parsing functions.
-         */
-
-        return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
-}
-
-static void write_env_var(FILE *f, const char *v) {
-        const char *p;
-
-        p = strchr(v, '=');
-        if (!p) {
-                /* Fallback */
-                fputs_unlocked(v, f);
-                fputc_unlocked('\n', f);
-                return;
-        }
-
-        p++;
-        fwrite_unlocked(v, 1, p-v, f);
-
-        if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
-                fputc_unlocked('\"', f);
-
-                for (; *p; p++) {
-                        if (strchr(SHELL_NEED_ESCAPE, *p))
-                                fputc_unlocked('\\', f);
-
-                        fputc_unlocked(*p, f);
-                }
-
-                fputc_unlocked('\"', f);
-        } else
-                fputs_unlocked(p, f);
-
-        fputc_unlocked('\n', f);
-}
-
-int write_env_file(const char *fname, char **l) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
-        char **i;
-        int r;
-
-        assert(fname);
-
-        r = fopen_temporary(fname, &f, &p);
-        if (r < 0)
-                return r;
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-        (void) fchmod_umask(fileno(f), 0644);
-
-        STRV_FOREACH(i, l)
-                write_env_var(f, *i);
-
-        r = fflush_and_check(f);
-        if (r >= 0) {
-                if (rename(p, fname) >= 0)
-                        return 0;
-
-                r = -errno;
-        }
-
-        unlink(p);
-        return r;
-}
-
-int executable_is_script(const char *path, char **interpreter) {
-        _cleanup_free_ char *line = NULL;
-        size_t len;
-        char *ans;
-        int r;
-
-        assert(path);
-
-        r = read_one_line_file(path, &line);
-        if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */
-                return 0;
-        if (r < 0)
-                return r;
-
-        if (!startswith(line, "#!"))
-                return 0;
-
-        ans = strstrip(line + 2);
-        len = strcspn(ans, " \t");
-
-        if (len == 0)
-                return 0;
-
-        ans = strndup(ans, len);
-        if (!ans)
-                return -ENOMEM;
-
-        *interpreter = ans;
-        return 1;
-}
-#endif /* NM_IGNORED */
-
-/**
- * Retrieve one field from a file like /proc/self/status.  pattern
- * should not include whitespace or the delimiter (':'). pattern matches only
- * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
- * zeros after the ':' will be skipped. field must be freed afterwards.
- * terminator specifies the terminating characters of the field value (not
- * included in the value).
- */
-int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
-        _cleanup_free_ char *status = NULL;
-        char *t, *f;
-        size_t len;
-        int r;
-
-        assert(terminator);
-        assert(filename);
-        assert(pattern);
-        assert(field);
-
-        r = read_full_file(filename, &status, NULL);
-        if (r < 0)
-                return r;
-
-        t = status;
-
-        do {
-                bool pattern_ok;
-
-                do {
-                        t = strstr(t, pattern);
-                        if (!t)
-                                return -ENOENT;
-
-                        /* Check that pattern occurs in beginning of line. */
-                        pattern_ok = (t == status || t[-1] == '\n');
-
-                        t += strlen(pattern);
-
-                } while (!pattern_ok);
-
-                t += strspn(t, " \t");
-                if (!*t)
-                        return -ENOENT;
-
-        } while (*t != ':');
-
-        t++;
-
-        if (*t) {
-                t += strspn(t, " \t");
-
-                /* Also skip zeros, because when this is used for
-                 * capabilities, we don't want the zeros. This way the
-                 * same capability set always maps to the same string,
-                 * irrespective of the total capability set size. For
-                 * other numbers it shouldn't matter. */
-                t += strspn(t, "0");
-                /* Back off one char if there's nothing but whitespace
-                   and zeros */
-                if (!*t || isspace(*t))
-                        t--;
-        }
-
-        len = strcspn(t, terminator);
-
-        f = strndup(t, len);
-        if (!f)
-                return -ENOMEM;
-
-        *field = f;
-        return 0;
-}
-
-DIR *xopendirat(int fd, const char *name, int flags) {
-        int nfd;
-        DIR *d;
-
-        assert(!(flags & O_CREAT));
-
-        nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
-        if (nfd < 0)
-                return NULL;
-
-        d = fdopendir(nfd);
-        if (!d) {
-                safe_close(nfd);
-                return NULL;
-        }
-
-        return d;
-}
-
-#if 0 /* NM_IGNORED */
-static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
-        char **i;
-
-        assert(path);
-        assert(mode);
-        assert(_f);
-
-        if (!path_strv_resolve_uniq(search, root))
-                return -ENOMEM;
-
-        STRV_FOREACH(i, search) {
-                _cleanup_free_ char *p = NULL;
-                FILE *f;
-
-                if (root)
-                        p = strjoin(root, *i, "/", path);
-                else
-                        p = strjoin(*i, "/", path);
-                if (!p)
-                        return -ENOMEM;
-
-                f = fopen(p, mode);
-                if (f) {
-                        *_f = f;
-                        return 0;
-                }
-
-                if (errno != ENOENT)
-                        return -errno;
-        }
-
-        return -ENOENT;
-}
-
-int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
-        _cleanup_strv_free_ char **copy = NULL;
-
-        assert(path);
-        assert(mode);
-        assert(_f);
-
-        if (path_is_absolute(path)) {
-                FILE *f;
-
-                f = fopen(path, mode);
-                if (f) {
-                        *_f = f;
-                        return 0;
-                }
-
-                return -errno;
-        }
-
-        copy = strv_copy((char**) search);
-        if (!copy)
-                return -ENOMEM;
-
-        return search_and_fopen_internal(path, mode, root, copy, _f);
-}
-
-int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
-        _cleanup_strv_free_ char **s = NULL;
-
-        if (path_is_absolute(path)) {
-                FILE *f;
-
-                f = fopen(path, mode);
-                if (f) {
-                        *_f = f;
-                        return 0;
-                }
-
-                return -errno;
-        }
-
-        s = strv_split_nulstr(search);
-        if (!s)
-                return -ENOMEM;
-
-        return search_and_fopen_internal(path, mode, root, s, _f);
-}
-#endif /* NM_IGNORED */
-
-int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
-        FILE *f;
-        char *t;
-        int r, fd;
-
-        assert(path);
-        assert(_f);
-        assert(_temp_path);
-
-        r = tempfn_xxxxxx(path, NULL, &t);
-        if (r < 0)
-                return r;
-
-        fd = mkostemp_safe(t);
-        if (fd < 0) {
-                free(t);
-                return -errno;
-        }
-
-        f = fdopen(fd, "we");
-        if (!f) {
-                unlink_noerrno(t);
-                free(t);
-                safe_close(fd);
-                return -errno;
-        }
-
-        *_f = f;
-        *_temp_path = t;
-
-        return 0;
-}
-
-int fflush_and_check(FILE *f) {
-        assert(f);
-
-        errno = 0;
-        fflush(f);
-
-        if (ferror(f))
-                return errno > 0 ? -errno : -EIO;
-
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-int fflush_sync_and_check(FILE *f) {
-        int r;
-
-        assert(f);
-
-        r = fflush_and_check(f);
-        if (r < 0)
-                return r;
-
-        if (fsync(fileno(f)) < 0)
-                return -errno;
-
-        r = fsync_directory_of_file(fileno(f));
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-/* This is much like mkostemp() but is subject to umask(). */
-int mkostemp_safe(char *pattern) {
-        _cleanup_umask_ mode_t u = 0;
-        int fd;
-
-        assert(pattern);
-
-        u = umask(077);
-
-        fd = mkostemp(pattern, O_CLOEXEC);
-        if (fd < 0)
-                return -errno;
-
-        return fd;
-}
-
-int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
-        const char *fn;
-        char *t;
-
-        assert(ret);
-
-        if (isempty(p))
-                return -EINVAL;
-        if (path_equal(p, "/"))
-                return -EINVAL;
-
-        /*
-         * Turns this:
-         *         /foo/bar/waldo
-         *
-         * Into this:
-         *         /foo/bar/.#<extra>waldoXXXXXX
-         */
-
-        fn = basename(p);
-        if (!filename_is_valid(fn))
-                return -EINVAL;
-
-        extra = strempty(extra);
-
-        t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
-        if (!t)
-                return -ENOMEM;
-
-        strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
-
-        *ret = path_simplify(t, false);
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-int tempfn_random(const char *p, const char *extra, char **ret) {
-        const char *fn;
-        char *t, *x;
-        uint64_t u;
-        unsigned i;
-
-        assert(ret);
-
-        if (isempty(p))
-                return -EINVAL;
-        if (path_equal(p, "/"))
-                return -EINVAL;
-
-        /*
-         * Turns this:
-         *         /foo/bar/waldo
-         *
-         * Into this:
-         *         /foo/bar/.#<extra>waldobaa2a261115984a9
-         */
-
-        fn = basename(p);
-        if (!filename_is_valid(fn))
-                return -EINVAL;
-
-        extra = strempty(extra);
-
-        t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
-        if (!t)
-                return -ENOMEM;
-
-        x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
-
-        u = random_u64();
-        for (i = 0; i < 16; i++) {
-                *(x++) = hexchar(u & 0xF);
-                u >>= 4;
-        }
-
-        *x = 0;
-
-        *ret = path_simplify(t, false);
-        return 0;
-}
-
-int tempfn_random_child(const char *p, const char *extra, char **ret) {
-        char *t, *x;
-        uint64_t u;
-        unsigned i;
-        int r;
-
-        assert(ret);
-
-        /* Turns this:
-         *         /foo/bar/waldo
-         * Into this:
-         *         /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
-         */
-
-        if (!p) {
-                r = tmp_dir(&p);
-                if (r < 0)
-                        return r;
-        }
-
-        extra = strempty(extra);
-
-        t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
-        if (!t)
-                return -ENOMEM;
-
-        if (isempty(p))
-                x = stpcpy(stpcpy(t, ".#"), extra);
-        else
-                x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
-
-        u = random_u64();
-        for (i = 0; i < 16; i++) {
-                *(x++) = hexchar(u & 0xF);
-                u >>= 4;
-        }
-
-        *x = 0;
-
-        *ret = path_simplify(t, false);
-        return 0;
-}
-
-int write_timestamp_file_atomic(const char *fn, usec_t n) {
-        char ln[DECIMAL_STR_MAX(n)+2];
-
-        /* Creates a "timestamp" file, that contains nothing but a
-         * usec_t timestamp, formatted in ASCII. */
-
-        if (n <= 0 || n >= USEC_INFINITY)
-                return -ERANGE;
-
-        xsprintf(ln, USEC_FMT "\n", n);
-
-        return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
-}
-
-int read_timestamp_file(const char *fn, usec_t *ret) {
-        _cleanup_free_ char *ln = NULL;
-        uint64_t t;
-        int r;
-
-        r = read_one_line_file(fn, &ln);
-        if (r < 0)
-                return r;
-
-        r = safe_atou64(ln, &t);
-        if (r < 0)
-                return r;
-
-        if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
-                return -ERANGE;
-
-        *ret = (usec_t) t;
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
-        int r;
-
-        assert(s);
-
-        /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
-         * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
-         * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
-         * element, but not before the first one. */
-
-        if (!f)
-                f = stdout;
-
-        if (space) {
-                if (!separator)
-                        separator = " ";
-
-                if (*space) {
-                        r = fputs(separator, f);
-                        if (r < 0)
-                                return r;
-                }
-
-                *space = true;
-        }
-
-        return fputs(s, f);
-}
-
-#if 0 /* NM_IGNORED */
-int open_tmpfile_unlinkable(const char *directory, int flags) {
-        char *p;
-        int fd, r;
-
-        if (!directory) {
-                r = tmp_dir(&directory);
-                if (r < 0)
-                        return r;
-        } else if (isempty(directory))
-                return -EINVAL;
-
-        /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
-
-        /* Try O_TMPFILE first, if it is supported */
-        fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
-        if (fd >= 0)
-                return fd;
-
-        /* Fall back to unguessable name + unlinking */
-        p = strjoina(directory, "/systemd-tmp-XXXXXX");
-
-        fd = mkostemp_safe(p);
-        if (fd < 0)
-                return fd;
-
-        (void) unlink(p);
-
-        return fd;
-}
-
-int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
-        _cleanup_free_ char *tmp = NULL;
-        int r, fd;
-
-        assert(target);
-        assert(ret_path);
-
-        /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
-        assert((flags & O_EXCL) == 0);
-
-        /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
-         * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
-         * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
-
-        fd = open_parent(target, O_TMPFILE|flags, 0640);
-        if (fd >= 0) {
-                *ret_path = NULL;
-                return fd;
-        }
-
-        log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target);
-
-        r = tempfn_random(target, NULL, &tmp);
-        if (r < 0)
-                return r;
-
-        fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
-        if (fd < 0)
-                return -errno;
-
-        *ret_path = TAKE_PTR(tmp);
-
-        return fd;
-}
-
-int open_serialization_fd(const char *ident) {
-        int fd = -1;
-
-        fd = memfd_create(ident, MFD_CLOEXEC);
-        if (fd < 0) {
-                const char *path;
-
-                path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
-                fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
-                if (fd < 0)
-                        return fd;
-
-                log_debug("Serializing %s to %s.", ident, path);
-        } else
-                log_debug("Serializing %s to memfd.", ident);
-
-        return fd;
-}
-
-int link_tmpfile(int fd, const char *path, const char *target) {
-
-        assert(fd >= 0);
-        assert(target);
-
-        /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
-         * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
-         * on the directory, and renameat2() is used instead.
-         *
-         * Note that in both cases we will not replace existing files. This is because linkat() does not support this
-         * operation currently (renameat2() does), and there is no nice way to emulate this. */
-
-        if (path) {
-                if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
-                        return -errno;
-        } else {
-                char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
-
-                xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
-
-                if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
-                        return -errno;
-        }
-
-        return 0;
-}
-
-int read_nul_string(FILE *f, char **ret) {
-        _cleanup_free_ char *x = NULL;
-        size_t allocated = 0, n = 0;
-
-        assert(f);
-        assert(ret);
-
-        /* Reads a NUL-terminated string from the specified file. */
-
-        for (;;) {
-                int c;
-
-                if (!GREEDY_REALLOC(x, allocated, n+2))
-                        return -ENOMEM;
-
-                c = fgetc(f);
-                if (c == 0) /* Terminate at NUL byte */
-                        break;
-                if (c == EOF) {
-                        if (ferror(f))
-                                return -errno;
-                        break; /* Terminate at EOF */
-                }
-
-                x[n++] = (char) c;
-        }
-
-        if (x)
-                x[n] = 0;
-        else {
-                x = new0(char, 1);
-                if (!x)
-                        return -ENOMEM;
-        }
-
-        *ret = TAKE_PTR(x);
-
-        return 0;
-}
-
-int mkdtemp_malloc(const char *template, char **ret) {
-        _cleanup_free_ char *p = NULL;
-        int r;
-
-        assert(ret);
-
-        if (template)
-                p = strdup(template);
-        else {
-                const char *tmp;
-
-                r = tmp_dir(&tmp);
-                if (r < 0)
-                        return r;
-
-                p = strjoin(tmp, "/XXXXXX");
-        }
-        if (!p)
-                return -ENOMEM;
-
-        if (!mkdtemp(p))
-                return -errno;
-
-        *ret = TAKE_PTR(p);
-        return 0;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
-
-int read_line(FILE *f, size_t limit, char **ret) {
-        _cleanup_free_ char *buffer = NULL;
-        size_t n = 0, allocated = 0, count = 0;
-
-        assert(f);
-
-        /* Something like a bounded version of getline().
-         *
-         * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
-         * returned.
-         *
-         * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
-         * the number of characters in the returned string). When EOF is hit, 0 is returned.
-         *
-         * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
-         * delimiters. If the limit is hit we fail and return -ENOBUFS.
-         *
-         * If a line shall be skipped ret may be initialized as NULL. */
-
-        if (ret) {
-                if (!GREEDY_REALLOC(buffer, allocated, 1))
-                        return -ENOMEM;
-        }
-
-        {
-                _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
-                flockfile(f);
-
-                for (;;) {
-                        int c;
-
-                        if (n >= limit)
-                                return -ENOBUFS;
-
-                        errno = 0;
-                        c = fgetc_unlocked(f);
-                        if (c == EOF) {
-                                /* if we read an error, and have no data to return, then propagate the error */
-                                if (ferror_unlocked(f) && n == 0)
-                                        return errno > 0 ? -errno : -EIO;
-
-                                break;
-                        }
-
-                        count++;
-
-                        if (IN_SET(c, '\n', 0)) /* Reached a delimiter */
-                                break;
-
-                        if (ret) {
-                                if (!GREEDY_REALLOC(buffer, allocated, n + 2))
-                                        return -ENOMEM;
-
-                                buffer[n] = (char) c;
-                        }
-
-                        n++;
-                }
-        }
-
-        if (ret) {
-                buffer[n] = 0;
-
-                *ret = TAKE_PTR(buffer);
-        }
-
-        return (int) count;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h
deleted file mode 100644
index 77e6206e..00000000
--- a/src/systemd/src/basic/fileio.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <dirent.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "macro.h"
-#include "time-util.h"
-
-typedef enum {
-        WRITE_STRING_FILE_CREATE            = 1 << 0,
-        WRITE_STRING_FILE_ATOMIC            = 1 << 1,
-        WRITE_STRING_FILE_AVOID_NEWLINE     = 1 << 2,
-        WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 3,
-        WRITE_STRING_FILE_SYNC              = 1 << 4,
-        WRITE_STRING_FILE_DISABLE_BUFFER    = 1 << 5,
-
-        /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
-           more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
-           and friends. */
-
-} WriteStringFileFlags;
-
-int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts);
-static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) {
-        return write_string_stream_ts(f, line, flags, NULL);
-}
-int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
-static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
-        return write_string_file_ts(fn, line, flags, NULL);
-}
-
-int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4);
-
-int read_one_line_file(const char *fn, char **line);
-int read_full_file(const char *fn, char **contents, size_t *size);
-int read_full_stream(FILE *f, char **contents, size_t *size);
-
-int verify_file(const char *fn, const char *blob, bool accept_extra_nl);
-
-int parse_env_filev(FILE *f, const char *fname, const char *separator, va_list ap);
-int parse_env_file(FILE *f, const char *fname, const char *separator, ...) _sentinel_;
-int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
-int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
-
-int merge_env_file(char ***env, FILE *f, const char *fname);
-
-int write_env_file(const char *fname, char **l);
-
-int executable_is_script(const char *path, char **interpreter);
-
-int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field);
-
-DIR *xopendirat(int dirfd, const char *name, int flags);
-
-int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
-int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
-
-#define FOREACH_LINE(line, f, on_error)                         \
-        for (;;)                                                \
-                if (!fgets(line, sizeof(line), f)) {            \
-                        if (ferror(f)) {                        \
-                                on_error;                       \
-                        }                                       \
-                        break;                                  \
-                } else
-
-int fflush_and_check(FILE *f);
-int fflush_sync_and_check(FILE *f);
-
-int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
-int mkostemp_safe(char *pattern);
-
-int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
-int tempfn_random(const char *p, const char *extra, char **ret);
-int tempfn_random_child(const char *p, const char *extra, char **ret);
-
-int write_timestamp_file_atomic(const char *fn, usec_t n);
-int read_timestamp_file(const char *fn, usec_t *ret);
-
-int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);
-
-int open_tmpfile_unlinkable(const char *directory, int flags);
-int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
-int open_serialization_fd(const char *ident);
-
-int link_tmpfile(int fd, const char *path, const char *target);
-
-int read_nul_string(FILE *f, char **ret);
-
-int mkdtemp_malloc(const char *template, char **ret);
-
-int read_line(FILE *f, size_t limit, char **ret);
diff --git a/src/systemd/src/basic/fs-util.c b/src/systemd/src/basic/fs-util.c
deleted file mode 100644
index 8c19e9c7..00000000
--- a/src/systemd/src/basic/fs-util.c
+++ /dev/null
@@ -1,1256 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <linux/magic.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "mkdir.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "stat-util.h"
-#include "stdio-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-#include "user-util.h"
-#include "util.h"
-
-int unlink_noerrno(const char *path) {
-        PROTECT_ERRNO;
-        int r;
-
-        r = unlink(path);
-        if (r < 0)
-                return -errno;
-
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-int rmdir_parents(const char *path, const char *stop) {
-        size_t l;
-        int r = 0;
-
-        assert(path);
-        assert(stop);
-
-        l = strlen(path);
-
-        /* Skip trailing slashes */
-        while (l > 0 && path[l-1] == '/')
-                l--;
-
-        while (l > 0) {
-                char *t;
-
-                /* Skip last component */
-                while (l > 0 && path[l-1] != '/')
-                        l--;
-
-                /* Skip trailing slashes */
-                while (l > 0 && path[l-1] == '/')
-                        l--;
-
-                if (l <= 0)
-                        break;
-
-                t = strndup(path, l);
-                if (!t)
-                        return -ENOMEM;
-
-                if (path_startswith(stop, t)) {
-                        free(t);
-                        return 0;
-                }
-
-                r = rmdir(t);
-                free(t);
-
-                if (r < 0)
-                        if (errno != ENOENT)
-                                return -errno;
-        }
-
-        return 0;
-}
-
-int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
-        struct stat buf;
-        int ret;
-
-        ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
-        if (ret >= 0)
-                return 0;
-
-        /* renameat2() exists since Linux 3.15, btrfs added support for it later.
-         * If it is not implemented, fallback to another method. */
-        if (!IN_SET(errno, EINVAL, ENOSYS))
-                return -errno;
-
-        /* The link()/unlink() fallback does not work on directories. But
-         * renameat() without RENAME_NOREPLACE gives the same semantics on
-         * directories, except when newpath is an *empty* directory. This is
-         * good enough. */
-        ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
-        if (ret >= 0 && S_ISDIR(buf.st_mode)) {
-                ret = renameat(olddirfd, oldpath, newdirfd, newpath);
-                return ret >= 0 ? 0 : -errno;
-        }
-
-        /* If it is not a directory, use the link()/unlink() fallback. */
-        ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
-        if (ret < 0)
-                return -errno;
-
-        ret = unlinkat(olddirfd, oldpath, 0);
-        if (ret < 0) {
-                /* backup errno before the following unlinkat() alters it */
-                ret = errno;
-                (void) unlinkat(newdirfd, newpath, 0);
-                errno = ret;
-                return -errno;
-        }
-
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-int readlinkat_malloc(int fd, const char *p, char **ret) {
-        size_t l = 100;
-        int r;
-
-        assert(p);
-        assert(ret);
-
-        for (;;) {
-                char *c;
-                ssize_t n;
-
-                c = new(char, l);
-                if (!c)
-                        return -ENOMEM;
-
-                n = readlinkat(fd, p, c, l-1);
-                if (n < 0) {
-                        r = -errno;
-                        free(c);
-                        return r;
-                }
-
-                if ((size_t) n < l-1) {
-                        c[n] = 0;
-                        *ret = c;
-                        return 0;
-                }
-
-                free(c);
-                l *= 2;
-        }
-}
-
-int readlink_malloc(const char *p, char **ret) {
-        return readlinkat_malloc(AT_FDCWD, p, ret);
-}
-
-#if 0 /* NM_IGNORED */
-int readlink_value(const char *p, char **ret) {
-        _cleanup_free_ char *link = NULL;
-        char *value;
-        int r;
-
-        r = readlink_malloc(p, &link);
-        if (r < 0)
-                return r;
-
-        value = basename(link);
-        if (!value)
-                return -ENOENT;
-
-        value = strdup(value);
-        if (!value)
-                return -ENOMEM;
-
-        *ret = value;
-
-        return 0;
-}
-
-int readlink_and_make_absolute(const char *p, char **r) {
-        _cleanup_free_ char *target = NULL;
-        char *k;
-        int j;
-
-        assert(p);
-        assert(r);
-
-        j = readlink_malloc(p, &target);
-        if (j < 0)
-                return j;
-
-        k = file_in_same_dir(p, target);
-        if (!k)
-                return -ENOMEM;
-
-        *r = k;
-        return 0;
-}
-
-int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
-        assert(path);
-
-        /* Under the assumption that we are running privileged we
-         * first change the access mode and only then hand out
-         * ownership to avoid a window where access is too open. */
-
-        if (mode != MODE_INVALID)
-                if (chmod(path, mode) < 0)
-                        return -errno;
-
-        if (uid != UID_INVALID || gid != GID_INVALID)
-                if (chown(path, uid, gid) < 0)
-                        return -errno;
-
-        return 0;
-}
-
-int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
-        /* Under the assumption that we are running privileged we
-         * first change the access mode and only then hand out
-         * ownership to avoid a window where access is too open. */
-
-        if (mode != MODE_INVALID)
-                if (fchmod(fd, mode) < 0)
-                        return -errno;
-
-        if (uid != UID_INVALID || gid != GID_INVALID)
-                if (fchown(fd, uid, gid) < 0)
-                        return -errno;
-
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-int fchmod_umask(int fd, mode_t m) {
-        mode_t u;
-        int r;
-
-        u = umask(0777);
-        r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
-        umask(u);
-
-        return r;
-}
-
-#if 0 /* NM_IGNORED */
-int fchmod_opath(int fd, mode_t m) {
-        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
-
-        /* This function operates also on fd that might have been opened with
-         * O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
-         * fchownat() does. */
-
-        xsprintf(procfs_path, "/proc/self/fd/%i", fd);
-
-        if (chmod(procfs_path, m) < 0)
-                return -errno;
-
-        return 0;
-}
-
-int fd_warn_permissions(const char *path, int fd) {
-        struct stat st;
-
-        if (fstat(fd, &st) < 0)
-                return -errno;
-
-        if (st.st_mode & 0111)
-                log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
-
-        if (st.st_mode & 0002)
-                log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
-
-        if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
-                log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
-
-        return 0;
-}
-
-int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
-        char fdpath[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
-        _cleanup_close_ int fd = -1;
-        int r, ret = 0;
-
-        assert(path);
-
-        /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink
-         * itself which is updated, not its target
-         *
-         * Returns the first error we encounter, but tries to apply as much as possible. */
-
-        if (parents)
-                (void) mkdir_parents(path, 0755);
-
-        /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in
-         * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and
-         * won't trigger any driver magic or so. */
-        fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW);
-        if (fd < 0) {
-                if (errno != ENOENT)
-                        return -errno;
-
-                /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file
-                 * here, and nothing else */
-                fd = open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode);
-                if (fd < 0)
-                        return -errno;
-        }
-
-        /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode,
-         * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object — which is
-         * something fchown(), fchmod(), futimensat() don't allow. */
-        xsprintf(fdpath, "/proc/self/fd/%i", fd);
-
-        if (mode != MODE_INVALID)
-                if (chmod(fdpath, mode) < 0)
-                        ret = -errno;
-
-        if (uid_is_valid(uid) || gid_is_valid(gid))
-                if (chown(fdpath, uid, gid) < 0 && ret >= 0)
-                        ret = -errno;
-
-        if (stamp != USEC_INFINITY) {
-                struct timespec ts[2];
-
-                timespec_store(&ts[0], stamp);
-                ts[1] = ts[0];
-                r = utimensat(AT_FDCWD, fdpath, ts, 0);
-        } else
-                r = utimensat(AT_FDCWD, fdpath, NULL, 0);
-        if (r < 0 && ret >= 0)
-                return -errno;
-
-        return ret;
-}
-
-int touch(const char *path) {
-        return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
-}
-
-int symlink_idempotent(const char *from, const char *to) {
-        int r;
-
-        assert(from);
-        assert(to);
-
-        if (symlink(from, to) < 0) {
-                _cleanup_free_ char *p = NULL;
-
-                if (errno != EEXIST)
-                        return -errno;
-
-                r = readlink_malloc(to, &p);
-                if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
-                        return -EEXIST;
-                if (r < 0) /* Any other error? In that case propagate it as is */
-                        return r;
-
-                if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
-                        return -EEXIST;
-        }
-
-        return 0;
-}
-
-int symlink_atomic(const char *from, const char *to) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        assert(from);
-        assert(to);
-
-        r = tempfn_random(to, NULL, &t);
-        if (r < 0)
-                return r;
-
-        if (symlink(from, t) < 0)
-                return -errno;
-
-        if (rename(t, to) < 0) {
-                unlink_noerrno(t);
-                return -errno;
-        }
-
-        return 0;
-}
-
-int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        assert(path);
-
-        r = tempfn_random(path, NULL, &t);
-        if (r < 0)
-                return r;
-
-        if (mknod(t, mode, dev) < 0)
-                return -errno;
-
-        if (rename(t, path) < 0) {
-                unlink_noerrno(t);
-                return -errno;
-        }
-
-        return 0;
-}
-
-int mkfifo_atomic(const char *path, mode_t mode) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        assert(path);
-
-        r = tempfn_random(path, NULL, &t);
-        if (r < 0)
-                return r;
-
-        if (mkfifo(t, mode) < 0)
-                return -errno;
-
-        if (rename(t, path) < 0) {
-                unlink_noerrno(t);
-                return -errno;
-        }
-
-        return 0;
-}
-
-int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        assert(path);
-
-        if (path_is_absolute(path))
-                return mkfifo_atomic(path, mode);
-
-        /* We're only interested in the (random) filename.  */
-        r = tempfn_random_child("", NULL, &t);
-        if (r < 0)
-                return r;
-
-        if (mkfifoat(dirfd, t, mode) < 0)
-                return -errno;
-
-        if (renameat(dirfd, t, dirfd, path) < 0) {
-                unlink_noerrno(t);
-                return -errno;
-        }
-
-        return 0;
-}
-
-int get_files_in_directory(const char *path, char ***list) {
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-        size_t bufsize = 0, n = 0;
-        _cleanup_strv_free_ char **l = NULL;
-
-        assert(path);
-
-        /* Returns all files in a directory in *list, and the number
-         * of files as return value. If list is NULL returns only the
-         * number. */
-
-        d = opendir(path);
-        if (!d)
-                return -errno;
-
-        FOREACH_DIRENT_ALL(de, d, return -errno) {
-                dirent_ensure_type(d, de);
-
-                if (!dirent_is_file(de))
-                        continue;
-
-                if (list) {
-                        /* one extra slot is needed for the terminating NULL */
-                        if (!GREEDY_REALLOC(l, bufsize, n + 2))
-                                return -ENOMEM;
-
-                        l[n] = strdup(de->d_name);
-                        if (!l[n])
-                                return -ENOMEM;
-
-                        l[++n] = NULL;
-                } else
-                        n++;
-        }
-
-        if (list)
-                *list = TAKE_PTR(l);
-
-        return n;
-}
-
-static int getenv_tmp_dir(const char **ret_path) {
-        const char *n;
-        int r, ret = 0;
-
-        assert(ret_path);
-
-        /* We use the same order of environment variables python uses in tempfile.gettempdir():
-         * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
-        FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") {
-                const char *e;
-
-                e = secure_getenv(n);
-                if (!e)
-                        continue;
-                if (!path_is_absolute(e)) {
-                        r = -ENOTDIR;
-                        goto next;
-                }
-                if (!path_is_normalized(e)) {
-                        r = -EPERM;
-                        goto next;
-                }
-
-                r = is_dir(e, true);
-                if (r < 0)
-                        goto next;
-                if (r == 0) {
-                        r = -ENOTDIR;
-                        goto next;
-                }
-
-                *ret_path = e;
-                return 1;
-
-        next:
-                /* Remember first error, to make this more debuggable */
-                if (ret >= 0)
-                        ret = r;
-        }
-
-        if (ret < 0)
-                return ret;
-
-        *ret_path = NULL;
-        return ret;
-}
-
-static int tmp_dir_internal(const char *def, const char **ret) {
-        const char *e;
-        int r, k;
-
-        assert(def);
-        assert(ret);
-
-        r = getenv_tmp_dir(&e);
-        if (r > 0) {
-                *ret = e;
-                return 0;
-        }
-
-        k = is_dir(def, true);
-        if (k == 0)
-                k = -ENOTDIR;
-        if (k < 0)
-                return r < 0 ? r : k;
-
-        *ret = def;
-        return 0;
-}
-
-int var_tmp_dir(const char **ret) {
-
-        /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
-         * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
-         * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
-         * making it a variable that overrides all temporary file storage locations. */
-
-        return tmp_dir_internal("/var/tmp", ret);
-}
-
-int tmp_dir(const char **ret) {
-
-        /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
-         * backed by an in-memory file system: /tmp. */
-
-        return tmp_dir_internal("/tmp", ret);
-}
-
-int unlink_or_warn(const char *filename) {
-        if (unlink(filename) < 0 && errno != ENOENT)
-                /* If the file doesn't exist and the fs simply was read-only (in which
-                 * case unlink() returns EROFS even if the file doesn't exist), don't
-                 * complain */
-                if (errno != EROFS || access(filename, F_OK) >= 0)
-                        return log_error_errno(errno, "Failed to remove \"%s\": %m", filename);
-
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
-        char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
-        int r;
-
-        /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
-        xsprintf(path, "/proc/self/fd/%i", what);
-
-        r = inotify_add_watch(fd, path, mask);
-        if (r < 0)
-                return -errno;
-
-        return r;
-}
-
-#if 0 /* NM_IGNORED */
-static bool safe_transition(const struct stat *a, const struct stat *b) {
-        /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
-         * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
-         * making us believe we read something safe even though it isn't safe in the specific context we open it in. */
-
-        if (a->st_uid == 0) /* Transitioning from privileged to unprivileged is always fine */
-                return true;
-
-        return a->st_uid == b->st_uid; /* Otherwise we need to stay within the same UID */
-}
-
-int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
-        _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
-        _cleanup_close_ int fd = -1;
-        unsigned max_follow = CHASE_SYMLINKS_MAX; /* how many symlinks to follow before giving up and returning ELOOP */
-        struct stat previous_stat;
-        bool exists = true;
-        char *todo;
-        int r;
-
-        assert(path);
-
-        /* Either the file may be missing, or we return an fd to the final object, but both make no sense */
-        if (FLAGS_SET(flags, CHASE_NONEXISTENT | CHASE_OPEN))
-                return -EINVAL;
-
-        if (FLAGS_SET(flags, CHASE_STEP | CHASE_OPEN))
-                return -EINVAL;
-
-        if (isempty(path))
-                return -EINVAL;
-
-        /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
-         * symlinks relative to a root directory, instead of the root of the host.
-         *
-         * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
-         * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
-         * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
-         * prefixed accordingly.
-         *
-         * Algorithmically this operates on two path buffers: "done" are the components of the path we already
-         * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
-         * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
-         * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
-         * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
-         * at a minimum.
-         *
-         * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
-         * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
-         * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
-         * specified path.
-         *
-         * There are three ways to invoke this function:
-         *
-         * 1. Without CHASE_STEP or CHASE_OPEN: in this case the path is resolved and the normalized path is returned
-         *    in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set 0 is returned if the file
-         *    doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set >= 0 is returned if the destination was
-         *    found, -ENOENT if it doesn't.
-         *
-         * 2. With CHASE_OPEN: in this case the destination is opened after chasing it as O_PATH and this file
-         *    descriptor is returned as return value. This is useful to open files relative to some root
-         *    directory. Note that the returned O_PATH file descriptors must be converted into a regular one (using
-         *    fd_reopen() or such) before it can be used for reading/writing. CHASE_OPEN may not be combined with
-         *    CHASE_NONEXISTENT.
-         *
-         * 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first
-         *    symlink or ".." component of the path is resolved, and the resulting path is returned. This is useful if
-         *    a caller wants to trace the a path through the file system verbosely. Returns < 0 on error, > 0 if the
-         *    path is fully normalized, and == 0 for each normalization step. This may be combined with
-         *    CHASE_NONEXISTENT, in which case 1 is returned when a component is not found.
-         *
-         * */
-
-        /* A root directory of "/" or "" is identical to none */
-        if (empty_or_root(original_root))
-                original_root = NULL;
-
-        if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) {
-                /* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set
-                 * and doesn't care about any of the other special features we provide either. */
-                r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0));
-                if (r < 0)
-                        return -errno;
-
-                return r;
-        }
-
-        if (original_root) {
-                r = path_make_absolute_cwd(original_root, &root);
-                if (r < 0)
-                        return r;
-
-                if (flags & CHASE_PREFIX_ROOT) {
-
-                        /* We don't support relative paths in combination with a root directory */
-                        if (!path_is_absolute(path))
-                                return -EINVAL;
-
-                        path = prefix_roota(root, path);
-                }
-        }
-
-        r = path_make_absolute_cwd(path, &buffer);
-        if (r < 0)
-                return r;
-
-        fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
-        if (fd < 0)
-                return -errno;
-
-        if (flags & CHASE_SAFE) {
-                if (fstat(fd, &previous_stat) < 0)
-                        return -errno;
-        }
-
-        todo = buffer;
-        for (;;) {
-                _cleanup_free_ char *first = NULL;
-                _cleanup_close_ int child = -1;
-                struct stat st;
-                size_t n, m;
-
-                /* Determine length of first component in the path */
-                n = strspn(todo, "/");                  /* The slashes */
-                m = n + strcspn(todo + n, "/");         /* The entire length of the component */
-
-                /* Extract the first component. */
-                first = strndup(todo, m);
-                if (!first)
-                        return -ENOMEM;
-
-                todo += m;
-
-                /* Empty? Then we reached the end. */
-                if (isempty(first))
-                        break;
-
-                /* Just a single slash? Then we reached the end. */
-                if (path_equal(first, "/")) {
-                        /* Preserve the trailing slash */
-
-                        if (flags & CHASE_TRAIL_SLASH)
-                                if (!strextend(&done, "/", NULL))
-                                        return -ENOMEM;
-
-                        break;
-                }
-
-                /* Just a dot? Then let's eat this up. */
-                if (path_equal(first, "/."))
-                        continue;
-
-                /* Two dots? Then chop off the last bit of what we already found out. */
-                if (path_equal(first, "/..")) {
-                        _cleanup_free_ char *parent = NULL;
-                        _cleanup_close_ int fd_parent = -1;
-
-                        /* If we already are at the top, then going up will not change anything. This is in-line with
-                         * how the kernel handles this. */
-                        if (empty_or_root(done))
-                                continue;
-
-                        parent = dirname_malloc(done);
-                        if (!parent)
-                                return -ENOMEM;
-
-                        /* Don't allow this to leave the root dir.  */
-                        if (root &&
-                            path_startswith(done, root) &&
-                            !path_startswith(parent, root))
-                                continue;
-
-                        free_and_replace(done, parent);
-
-                        if (flags & CHASE_STEP)
-                                goto chased_one;
-
-                        fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH);
-                        if (fd_parent < 0)
-                                return -errno;
-
-                        if (flags & CHASE_SAFE) {
-                                if (fstat(fd_parent, &st) < 0)
-                                        return -errno;
-
-                                if (!safe_transition(&previous_stat, &st))
-                                        return -EPERM;
-
-                                previous_stat = st;
-                        }
-
-                        safe_close(fd);
-                        fd = TAKE_FD(fd_parent);
-
-                        continue;
-                }
-
-                /* Otherwise let's see what this is. */
-                child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH);
-                if (child < 0) {
-
-                        if (errno == ENOENT &&
-                            (flags & CHASE_NONEXISTENT) &&
-                            (isempty(todo) || path_is_normalized(todo))) {
-
-                                /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
-                                 * what we got so far. But don't allow this if the remaining path contains "../ or "./"
-                                 * or something else weird. */
-
-                                /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
-                                if (streq_ptr(done, "/"))
-                                        *done = '\0';
-
-                                if (!strextend(&done, first, todo, NULL))
-                                        return -ENOMEM;
-
-                                exists = false;
-                                break;
-                        }
-
-                        return -errno;
-                }
-
-                if (fstat(child, &st) < 0)
-                        return -errno;
-                if ((flags & CHASE_SAFE) &&
-                    !safe_transition(&previous_stat, &st))
-                        return -EPERM;
-
-                previous_stat = st;
-
-                if ((flags & CHASE_NO_AUTOFS) &&
-                    fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
-                        return -EREMOTE;
-
-                if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) {
-                        char *joined;
-
-                        _cleanup_free_ char *destination = NULL;
-
-                        /* This is a symlink, in this case read the destination. But let's make sure we don't follow
-                         * symlinks without bounds. */
-                        if (--max_follow <= 0)
-                                return -ELOOP;
-
-                        r = readlinkat_malloc(fd, first + n, &destination);
-                        if (r < 0)
-                                return r;
-                        if (isempty(destination))
-                                return -EINVAL;
-
-                        if (path_is_absolute(destination)) {
-
-                                /* An absolute destination. Start the loop from the beginning, but use the root
-                                 * directory as base. */
-
-                                safe_close(fd);
-                                fd = open(root ?: "/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
-                                if (fd < 0)
-                                        return -errno;
-
-                                if (flags & CHASE_SAFE) {
-                                        if (fstat(fd, &st) < 0)
-                                                return -errno;
-
-                                        if (!safe_transition(&previous_stat, &st))
-                                                return -EPERM;
-
-                                        previous_stat = st;
-                                }
-
-                                free(done);
-
-                                /* Note that we do not revalidate the root, we take it as is. */
-                                if (isempty(root))
-                                        done = NULL;
-                                else {
-                                        done = strdup(root);
-                                        if (!done)
-                                                return -ENOMEM;
-                                }
-
-                                /* Prefix what's left to do with what we just read, and start the loop again, but
-                                 * remain in the current directory. */
-                                joined = strjoin(destination, todo);
-                        } else
-                                joined = strjoin("/", destination, todo);
-                        if (!joined)
-                                return -ENOMEM;
-
-                        free(buffer);
-                        todo = buffer = joined;
-
-                        if (flags & CHASE_STEP)
-                                goto chased_one;
-
-                        continue;
-                }
-
-                /* If this is not a symlink, then let's just add the name we read to what we already verified. */
-                if (!done)
-                        done = TAKE_PTR(first);
-                else {
-                        /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
-                        if (streq(done, "/"))
-                                *done = '\0';
-
-                        if (!strextend(&done, first, NULL))
-                                return -ENOMEM;
-                }
-
-                /* And iterate again, but go one directory further down. */
-                safe_close(fd);
-                fd = TAKE_FD(child);
-        }
-
-        if (!done) {
-                /* Special case, turn the empty string into "/", to indicate the root directory. */
-                done = strdup("/");
-                if (!done)
-                        return -ENOMEM;
-        }
-
-        if (ret)
-                *ret = TAKE_PTR(done);
-
-        if (flags & CHASE_OPEN) {
-                /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by
-                 * opening /proc/self/fd/xyz. */
-
-                assert(fd >= 0);
-                return TAKE_FD(fd);
-        }
-
-        if (flags & CHASE_STEP)
-                return 1;
-
-        return exists;
-
-chased_one:
-        if (ret) {
-                char *c;
-
-                c = strjoin(strempty(done), todo);
-                if (!c)
-                        return -ENOMEM;
-
-                *ret = c;
-        }
-
-        return 0;
-}
-
-int chase_symlinks_and_open(
-                const char *path,
-                const char *root,
-                unsigned chase_flags,
-                int open_flags,
-                char **ret_path) {
-
-        _cleanup_close_ int path_fd = -1;
-        _cleanup_free_ char *p = NULL;
-        int r;
-
-        if (chase_flags & CHASE_NONEXISTENT)
-                return -EINVAL;
-
-        if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
-                /* Shortcut this call if none of the special features of this call are requested */
-                r = open(path, open_flags);
-                if (r < 0)
-                        return -errno;
-
-                return r;
-        }
-
-        path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
-        if (path_fd < 0)
-                return path_fd;
-
-        r = fd_reopen(path_fd, open_flags);
-        if (r < 0)
-                return r;
-
-        if (ret_path)
-                *ret_path = TAKE_PTR(p);
-
-        return r;
-}
-
-int chase_symlinks_and_opendir(
-                const char *path,
-                const char *root,
-                unsigned chase_flags,
-                char **ret_path,
-                DIR **ret_dir) {
-
-        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
-        _cleanup_close_ int path_fd = -1;
-        _cleanup_free_ char *p = NULL;
-        DIR *d;
-
-        if (!ret_dir)
-                return -EINVAL;
-        if (chase_flags & CHASE_NONEXISTENT)
-                return -EINVAL;
-
-        if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
-                /* Shortcut this call if none of the special features of this call are requested */
-                d = opendir(path);
-                if (!d)
-                        return -errno;
-
-                *ret_dir = d;
-                return 0;
-        }
-
-        path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
-        if (path_fd < 0)
-                return path_fd;
-
-        xsprintf(procfs_path, "/proc/self/fd/%i", path_fd);
-        d = opendir(procfs_path);
-        if (!d)
-                return -errno;
-
-        if (ret_path)
-                *ret_path = TAKE_PTR(p);
-
-        *ret_dir = d;
-        return 0;
-}
-
-int chase_symlinks_and_stat(
-                const char *path,
-                const char *root,
-                unsigned chase_flags,
-                char **ret_path,
-                struct stat *ret_stat) {
-
-        _cleanup_close_ int path_fd = -1;
-        _cleanup_free_ char *p = NULL;
-
-        assert(path);
-        assert(ret_stat);
-
-        if (chase_flags & CHASE_NONEXISTENT)
-                return -EINVAL;
-
-        if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
-                /* Shortcut this call if none of the special features of this call are requested */
-                if (stat(path, ret_stat) < 0)
-                        return -errno;
-
-                return 1;
-        }
-
-        path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
-        if (path_fd < 0)
-                return path_fd;
-
-        if (fstat(path_fd, ret_stat) < 0)
-                return -errno;
-
-        if (ret_path)
-                *ret_path = TAKE_PTR(p);
-
-        if (chase_flags & CHASE_OPEN)
-                return TAKE_FD(path_fd);
-
-        return 1;
-}
-
-int access_fd(int fd, int mode) {
-        char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
-        int r;
-
-        /* Like access() but operates on an already open fd */
-
-        xsprintf(p, "/proc/self/fd/%i", fd);
-        r = access(p, mode);
-        if (r < 0)
-                return -errno;
-
-        return r;
-}
-
-void unlink_tempfilep(char (*p)[]) {
-        /* If the file is created with mkstemp(), it will (almost always)
-         * change the suffix. Treat this as a sign that the file was
-         * successfully created. We ignore both the rare case where the
-         * original suffix is used and unlink failures. */
-        if (!endswith(*p, ".XXXXXX"))
-                (void) unlink_noerrno(*p);
-}
-
-int unlinkat_deallocate(int fd, const char *name, int flags) {
-        _cleanup_close_ int truncate_fd = -1;
-        struct stat st;
-        off_t l, bs;
-
-        /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other
-         * link to it. This is useful to ensure that other processes that might have the file open for reading won't be
-         * able to keep the data pinned on disk forever. This call is particular useful whenever we execute clean-up
-         * jobs ("vacuuming"), where we want to make sure the data is really gone and the disk space released and
-         * returned to the free pool.
-         *
-         * Deallocation is preferably done by FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE (👊) if supported, which means
-         * the file won't change size. That's a good thing since we shouldn't needlessly trigger SIGBUS in other
-         * programs that have mmap()ed the file. (The assumption here is that changing file contents to all zeroes
-         * underneath those programs is the better choice than simply triggering SIGBUS in them which truncation does.)
-         * However if hole punching is not implemented in the kernel or file system we'll fall back to normal file
-         * truncation (🔪), as our goal of deallocating the data space trumps our goal of being nice to readers (💐).
-         *
-         * Note that we attempt deallocation, but failure to succeed with that is not considered fatal, as long as the
-         * primary job – to delete the file – is accomplished. */
-
-        if ((flags & AT_REMOVEDIR) == 0) {
-                truncate_fd = openat(fd, name, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
-                if (truncate_fd < 0) {
-
-                        /* If this failed because the file doesn't exist propagate the error right-away. Also,
-                         * AT_REMOVEDIR wasn't set, and we tried to open the file for writing, which means EISDIR is
-                         * returned when this is a directory but we are not supposed to delete those, hence propagate
-                         * the error right-away too. */
-                        if (IN_SET(errno, ENOENT, EISDIR))
-                                return -errno;
-
-                        if (errno != ELOOP) /* don't complain if this is a symlink */
-                                log_debug_errno(errno, "Failed to open file '%s' for deallocation, ignoring: %m", name);
-                }
-        }
-
-        if (unlinkat(fd, name, flags) < 0)
-                return -errno;
-
-        if (truncate_fd < 0) /* Don't have a file handle, can't do more ☹️ */
-                return 0;
-
-        if (fstat(truncate_fd, &st) < 0) {
-                log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring.", name);
-                return 0;
-        }
-
-        if (!S_ISREG(st.st_mode) || st.st_blocks == 0 || st.st_nlink > 0)
-                return 0;
-
-        /* If this is a regular file, it actually took up space on disk and there are no other links it's time to
-         * punch-hole/truncate this to release the disk space. */
-
-        bs = MAX(st.st_blksize, 512);
-        l = DIV_ROUND_UP(st.st_size, bs) * bs; /* Round up to next block size */
-
-        if (fallocate(truncate_fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, 0, l) >= 0)
-                return 0; /* Successfully punched a hole! 😊 */
-
-        /* Fall back to truncation */
-        if (ftruncate(truncate_fd, 0) < 0) {
-                log_debug_errno(errno, "Failed to truncate file to 0, ignoring: %m");
-                return 0;
-        }
-
-        return 0;
-}
-
-int fsync_directory_of_file(int fd) {
-        _cleanup_free_ char *path = NULL;
-        _cleanup_close_ int dfd = -1;
-        int r;
-
-        r = fd_verify_regular(fd);
-        if (r < 0)
-                return r;
-
-        r = fd_get_path(fd, &path);
-        if (r < 0) {
-                log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m",
-                                fd,
-                                r == -EOPNOTSUPP ? ", ignoring" : "");
-
-                if (r == -EOPNOTSUPP)
-                        /* If /proc is not available, we're most likely running in some
-                         * chroot environment, and syncing the directory is not very
-                         * important in that case. Let's just silently do nothing. */
-                        return 0;
-
-                return r;
-        }
-
-        if (!path_is_absolute(path))
-                return -EINVAL;
-
-        dfd = open_parent(path, O_CLOEXEC, 0);
-        if (dfd < 0)
-                return dfd;
-
-        if (fsync(dfd) < 0)
-                return -errno;
-
-        return 0;
-}
-
-int open_parent(const char *path, int flags, mode_t mode) {
-        _cleanup_free_ char *parent = NULL;
-        int fd;
-
-        if (isempty(path))
-                return -EINVAL;
-        if (path_equal(path, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */
-                return -EINVAL;
-
-        parent = dirname_malloc(path);
-        if (!parent)
-                return -ENOMEM;
-
-        /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an
-         * O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */
-
-        if ((flags & O_PATH) == O_PATH)
-                flags |= O_DIRECTORY;
-        else if ((flags & O_TMPFILE) != O_TMPFILE)
-                flags |= O_DIRECTORY|O_RDONLY;
-
-        fd = open(parent, flags, mode);
-        if (fd < 0)
-                return -errno;
-
-        return fd;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/fs-util.h b/src/systemd/src/basic/fs-util.h
deleted file mode 100644
index 4b656258..00000000
--- a/src/systemd/src/basic/fs-util.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/inotify.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "time-util.h"
-#include "util.h"
-
-int unlink_noerrno(const char *path);
-
-int rmdir_parents(const char *path, const char *stop);
-
-int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
-
-int readlinkat_malloc(int fd, const char *p, char **ret);
-int readlink_malloc(const char *p, char **r);
-int readlink_value(const char *p, char **ret);
-int readlink_and_make_absolute(const char *p, char **r);
-
-int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
-int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid);
-
-int fchmod_umask(int fd, mode_t mode);
-int fchmod_opath(int fd, mode_t m);
-
-int fd_warn_permissions(const char *path, int fd);
-
-#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
-
-int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
-int touch(const char *path);
-
-int symlink_idempotent(const char *from, const char *to);
-
-int symlink_atomic(const char *from, const char *to);
-int mknod_atomic(const char *path, mode_t mode, dev_t dev);
-int mkfifo_atomic(const char *path, mode_t mode);
-int mkfifoat_atomic(int dir_fd, const char *path, mode_t mode);
-
-int get_files_in_directory(const char *path, char ***list);
-
-int tmp_dir(const char **ret);
-int var_tmp_dir(const char **ret);
-
-int unlink_or_warn(const char *filename);
-
-#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
-
-#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
-        for ((e) = &buffer.ev;                                \
-             (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
-             (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
-
-union inotify_event_buffer {
-        struct inotify_event ev;
-        uint8_t raw[INOTIFY_EVENT_MAX];
-};
-
-int inotify_add_watch_fd(int fd, int what, uint32_t mask);
-
-enum {
-        CHASE_PREFIX_ROOT = 1 << 0, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
-        CHASE_NONEXISTENT = 1 << 1, /* If set, it's OK if the path doesn't actually exist. */
-        CHASE_NO_AUTOFS   = 1 << 2, /* If set, return -EREMOTE if autofs mount point found */
-        CHASE_SAFE        = 1 << 3, /* If set, return EPERM if we ever traverse from unprivileged to privileged files or directories */
-        CHASE_OPEN        = 1 << 4, /* If set, return an O_PATH object to the final component */
-        CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
-        CHASE_STEP        = 1 << 6, /* If set, just execute a single step of the normalization */
-        CHASE_NOFOLLOW    = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */
-};
-
-/* How many iterations to execute before returning -ELOOP */
-#define CHASE_SYMLINKS_MAX 32
-
-int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
-
-int chase_symlinks_and_open(const char *path, const char *root, unsigned chase_flags, int open_flags, char **ret_path);
-int chase_symlinks_and_opendir(const char *path, const char *root, unsigned chase_flags, char **ret_path, DIR **ret_dir);
-int chase_symlinks_and_stat(const char *path, const char *root, unsigned chase_flags, char **ret_path, struct stat *ret_stat);
-
-/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */
-static inline void rmdir_and_free(char *p) {
-        PROTECT_ERRNO;
-        (void) rmdir(p);
-        free(p);
-}
-DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
-
-static inline void unlink_and_free(char *p) {
-        (void) unlink_noerrno(p);
-        free(p);
-}
-DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
-
-int access_fd(int fd, int mode);
-
-void unlink_tempfilep(char (*p)[]);
-int unlinkat_deallocate(int fd, const char *name, int flags);
-
-int fsync_directory_of_file(int fd);
-
-int open_parent(const char *path, int flags, mode_t mode);
diff --git a/src/systemd/src/basic/hash-funcs.c b/src/systemd/src/basic/hash-funcs.c
deleted file mode 100644
index fc2c4f78..00000000
--- a/src/systemd/src/basic/hash-funcs.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <string.h>
-
-#include "hash-funcs.h"
-#include "path-util.h"
-
-void string_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(p, strlen(p) + 1, state);
-}
-
-#if 0 /* NM_IGNORED */
-int string_compare_func(const void *a, const void *b) {
-        return strcmp(a, b);
-}
-
-const struct hash_ops string_hash_ops = {
-        .hash = string_hash_func,
-        .compare = string_compare_func
-};
-
-void path_hash_func(const void *p, struct siphash *state) {
-        const char *q = p;
-        size_t n;
-
-        assert(q);
-        assert(state);
-
-        /* Calculates a hash for a path in a way this duplicate inner slashes don't make a differences, and also
-         * whether there's a trailing slash or not. This fits well with the semantics of path_compare(), which does
-         * similar checks and also doesn't care for trailing slashes. Note that relative and absolute paths (i.e. those
-         * which begin in a slash or not) will hash differently though. */
-
-        n = strspn(q, "/");
-        if (n > 0) { /* Eat up initial slashes, and add one "/" to the hash for all of them */
-                siphash24_compress(q, 1, state);
-                q += n;
-        }
-
-        for (;;) {
-                /* Determine length of next component */
-                n = strcspn(q, "/");
-                if (n == 0) /* Reached the end? */
-                        break;
-
-                /* Add this component to the hash and skip over it */
-                siphash24_compress(q, n, state);
-                q += n;
-
-                /* How many slashes follow this component? */
-                n = strspn(q, "/");
-                if (q[n] == 0) /* Is this a trailing slash? If so, we are at the end, and don't care about the slashes anymore */
-                        break;
-
-                /* We are not add the end yet. Hash exactly one slash for all of the ones we just encountered. */
-                siphash24_compress(q, 1, state);
-                q += n;
-        }
-}
-
-int path_compare_func(const void *a, const void *b) {
-        return path_compare(a, b);
-}
-
-const struct hash_ops path_hash_ops = {
-        .hash = path_hash_func,
-        .compare = path_compare_func
-};
-#endif /* NM_IGNORED */
-
-void trivial_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(&p, sizeof(p), state);
-}
-
-int trivial_compare_func(const void *a, const void *b) {
-        return CMP(a, b);
-}
-
-const struct hash_ops trivial_hash_ops = {
-        .hash = trivial_hash_func,
-        .compare = trivial_compare_func
-};
-
-void uint64_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(p, sizeof(uint64_t), state);
-}
-
-int uint64_compare_func(const void *_a, const void *_b) {
-        uint64_t a, b;
-        a = *(const uint64_t*) _a;
-        b = *(const uint64_t*) _b;
-        return CMP(a, b);
-}
-
-const struct hash_ops uint64_hash_ops = {
-        .hash = uint64_hash_func,
-        .compare = uint64_compare_func
-};
-
-#if 0 /* NM_IGNORED */
-#if SIZEOF_DEV_T != 8
-void devt_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(p, sizeof(dev_t), state);
-}
-
-int devt_compare_func(const void *_a, const void *_b) {
-        dev_t a, b;
-        a = *(const dev_t*) _a;
-        b = *(const dev_t*) _b;
-        return CMP(a, b);
-}
-
-const struct hash_ops devt_hash_ops = {
-        .hash = devt_hash_func,
-        .compare = devt_compare_func
-};
-#endif
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/hash-funcs.h b/src/systemd/src/basic/hash-funcs.h
deleted file mode 100644
index fa45cfe2..00000000
--- a/src/systemd/src/basic/hash-funcs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include "macro.h"
-#include "siphash24.h"
-
-typedef void (*hash_func_t)(const void *p, struct siphash *state);
-typedef int (*compare_func_t)(const void *a, const void *b);
-
-struct hash_ops {
-        hash_func_t hash;
-        compare_func_t compare;
-};
-
-void string_hash_func(const void *p, struct siphash *state);
-int string_compare_func(const void *a, const void *b) _pure_;
-extern const struct hash_ops string_hash_ops;
-
-void path_hash_func(const void *p, struct siphash *state);
-int path_compare_func(const void *a, const void *b) _pure_;
-extern const struct hash_ops path_hash_ops;
-
-/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
- * or suchlike. */
-void trivial_hash_func(const void *p, struct siphash *state);
-int trivial_compare_func(const void *a, const void *b) _const_;
-extern const struct hash_ops trivial_hash_ops;
-
-/* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit
- * values indirectly, since they don't fit in a pointer. */
-void uint64_hash_func(const void *p, struct siphash *state);
-int uint64_compare_func(const void *a, const void *b) _pure_;
-extern const struct hash_ops uint64_hash_ops;
-
-/* On some archs dev_t is 32bit, and on others 64bit. And sometimes it's 64bit on 32bit archs, and sometimes 32bit on
- * 64bit archs. Yuck! */
-#if SIZEOF_DEV_T != 8
-void devt_hash_func(const void *p, struct siphash *state) _pure_;
-int devt_compare_func(const void *a, const void *b) _pure_;
-extern const struct hash_ops devt_hash_ops;
-#else
-#define devt_hash_func uint64_hash_func
-#define devt_compare_func uint64_compare_func
-#define devt_hash_ops uint64_hash_ops
-#endif
diff --git a/src/systemd/src/basic/hashmap.c b/src/systemd/src/basic/hashmap.c
deleted file mode 100644
index cfddeafe..00000000
--- a/src/systemd/src/basic/hashmap.c
+++ /dev/null
@@ -1,1988 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "env-util.h"
-#include "fileio.h"
-#include "hashmap.h"
-#include "macro.h"
-#include "mempool.h"
-#include "process-util.h"
-#include "random-util.h"
-#include "set.h"
-#include "siphash24.h"
-#include "string-util.h"
-#include "strv.h"
-#include "util.h"
-
-#if ENABLE_DEBUG_HASHMAP
-#include <pthread.h>
-#include "list.h"
-#endif
-
-/*
- * Implementation of hashmaps.
- * Addressing: open
- *   - uses less RAM compared to closed addressing (chaining), because
- *     our entries are small (especially in Sets, which tend to contain
- *     the majority of entries in systemd).
- * Collision resolution: Robin Hood
- *   - tends to equalize displacement of entries from their optimal buckets.
- * Probe sequence: linear
- *   - though theoretically worse than random probing/uniform hashing/double
- *     hashing, it is good for cache locality.
- *
- * References:
- * Celis, P. 1986. Robin Hood Hashing.
- * Ph.D. Dissertation. University of Waterloo, Waterloo, Ont., Canada, Canada.
- * https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf
- * - The results are derived for random probing. Suggests deletion with
- *   tombstones and two mean-centered search methods. None of that works
- *   well for linear probing.
- *
- * Janson, S. 2005. Individual displacements for linear probing hashing with different insertion policies.
- * ACM Trans. Algorithms 1, 2 (October 2005), 177-213.
- * DOI=10.1145/1103963.1103964 http://doi.acm.org/10.1145/1103963.1103964
- * http://www.math.uu.se/~svante/papers/sj157.pdf
- * - Applies to Robin Hood with linear probing. Contains remarks on
- *   the unsuitability of mean-centered search with linear probing.
- *
- * Viola, A. 2005. Exact distribution of individual displacements in linear probing hashing.
- * ACM Trans. Algorithms 1, 2 (October 2005), 214-242.
- * DOI=10.1145/1103963.1103965 http://doi.acm.org/10.1145/1103963.1103965
- * - Similar to Janson. Note that Viola writes about C_{m,n} (number of probes
- *   in a successful search), and Janson writes about displacement. C = d + 1.
- *
- * Goossaert, E. 2013. Robin Hood hashing: backward shift deletion.
- * http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/
- * - Explanation of backward shift deletion with pictures.
- *
- * Khuong, P. 2013. The Other Robin Hood Hashing.
- * http://www.pvk.ca/Blog/2013/11/26/the-other-robin-hood-hashing/
- * - Short summary of random vs. linear probing, and tombstones vs. backward shift.
- */
-
-/*
- * XXX Ideas for improvement:
- * For unordered hashmaps, randomize iteration order, similarly to Perl:
- * http://blog.booking.com/hardening-perls-hash-function.html
- */
-
-/* INV_KEEP_FREE = 1 / (1 - max_load_factor)
- * e.g. 1 / (1 - 0.8) = 5 ... keep one fifth of the buckets free. */
-#define INV_KEEP_FREE            5U
-
-/* Fields common to entries of all hashmap/set types */
-struct hashmap_base_entry {
-        const void *key;
-};
-
-/* Entry types for specific hashmap/set types
- * hashmap_base_entry must be at the beginning of each entry struct. */
-
-struct plain_hashmap_entry {
-        struct hashmap_base_entry b;
-        void *value;
-};
-
-struct ordered_hashmap_entry {
-        struct plain_hashmap_entry p;
-        unsigned iterate_next, iterate_previous;
-};
-
-struct set_entry {
-        struct hashmap_base_entry b;
-};
-
-/* In several functions it is advantageous to have the hash table extended
- * virtually by a couple of additional buckets. We reserve special index values
- * for these "swap" buckets. */
-#define _IDX_SWAP_BEGIN     (UINT_MAX - 3)
-#define IDX_PUT             (_IDX_SWAP_BEGIN + 0)
-#define IDX_TMP             (_IDX_SWAP_BEGIN + 1)
-#define _IDX_SWAP_END       (_IDX_SWAP_BEGIN + 2)
-
-#define IDX_FIRST           (UINT_MAX - 1) /* special index for freshly initialized iterators */
-#define IDX_NIL             UINT_MAX       /* special index value meaning "none" or "end" */
-
-assert_cc(IDX_FIRST == _IDX_SWAP_END);
-assert_cc(IDX_FIRST == _IDX_ITERATOR_FIRST);
-
-/* Storage space for the "swap" buckets.
- * All entry types can fit into a ordered_hashmap_entry. */
-struct swap_entries {
-        struct ordered_hashmap_entry e[_IDX_SWAP_END - _IDX_SWAP_BEGIN];
-};
-
-/* Distance from Initial Bucket */
-typedef uint8_t dib_raw_t;
-#define DIB_RAW_OVERFLOW ((dib_raw_t)0xfdU)   /* indicates DIB value is greater than representable */
-#define DIB_RAW_REHASH   ((dib_raw_t)0xfeU)   /* entry yet to be rehashed during in-place resize */
-#define DIB_RAW_FREE     ((dib_raw_t)0xffU)   /* a free bucket */
-#define DIB_RAW_INIT     ((char)DIB_RAW_FREE) /* a byte to memset a DIB store with when initializing */
-
-#define DIB_FREE UINT_MAX
-
-#if ENABLE_DEBUG_HASHMAP
-struct hashmap_debug_info {
-        LIST_FIELDS(struct hashmap_debug_info, debug_list);
-        unsigned max_entries;  /* high watermark of n_entries */
-
-        /* who allocated this hashmap */
-        int line;
-        const char *file;
-        const char *func;
-
-        /* fields to detect modification while iterating */
-        unsigned put_count;    /* counts puts into the hashmap */
-        unsigned rem_count;    /* counts removals from hashmap */
-        unsigned last_rem_idx; /* remembers last removal index */
-};
-
-/* Tracks all existing hashmaps. Get at it from gdb. See sd_dump_hashmaps.py */
-static LIST_HEAD(struct hashmap_debug_info, hashmap_debug_list);
-static pthread_mutex_t hashmap_debug_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#define HASHMAP_DEBUG_FIELDS struct hashmap_debug_info debug;
-
-#else /* !ENABLE_DEBUG_HASHMAP */
-#define HASHMAP_DEBUG_FIELDS
-#endif /* ENABLE_DEBUG_HASHMAP */
-
-enum HashmapType {
-        HASHMAP_TYPE_PLAIN,
-        HASHMAP_TYPE_ORDERED,
-        HASHMAP_TYPE_SET,
-        _HASHMAP_TYPE_MAX
-};
-
-struct _packed_ indirect_storage {
-        void *storage;                     /* where buckets and DIBs are stored */
-        uint8_t  hash_key[HASH_KEY_SIZE];  /* hash key; changes during resize */
-
-        unsigned n_entries;                /* number of stored entries */
-        unsigned n_buckets;                /* number of buckets */
-
-        unsigned idx_lowest_entry;         /* Index below which all buckets are free.
-                                              Makes "while(hashmap_steal_first())" loops
-                                              O(n) instead of O(n^2) for unordered hashmaps. */
-        uint8_t  _pad[3];                  /* padding for the whole HashmapBase */
-        /* The bitfields in HashmapBase complete the alignment of the whole thing. */
-};
-
-struct direct_storage {
-        /* This gives us 39 bytes on 64bit, or 35 bytes on 32bit.
-         * That's room for 4 set_entries + 4 DIB bytes + 3 unused bytes on 64bit,
-         *              or 7 set_entries + 7 DIB bytes + 0 unused bytes on 32bit. */
-        uint8_t storage[sizeof(struct indirect_storage)];
-};
-
-#define DIRECT_BUCKETS(entry_t) \
-        (sizeof(struct direct_storage) / (sizeof(entry_t) + sizeof(dib_raw_t)))
-
-/* We should be able to store at least one entry directly. */
-assert_cc(DIRECT_BUCKETS(struct ordered_hashmap_entry) >= 1);
-
-/* We have 3 bits for n_direct_entries. */
-assert_cc(DIRECT_BUCKETS(struct set_entry) < (1 << 3));
-
-/* Hashmaps with directly stored entries all use this shared hash key.
- * It's no big deal if the key is guessed, because there can be only
- * a handful of directly stored entries in a hashmap. When a hashmap
- * outgrows direct storage, it gets its own key for indirect storage. */
-static uint8_t shared_hash_key[HASH_KEY_SIZE];
-static bool shared_hash_key_initialized;
-
-/* Fields that all hashmap/set types must have */
-struct HashmapBase {
-        const struct hash_ops *hash_ops;  /* hash and compare ops to use */
-
-        union _packed_ {
-                struct indirect_storage indirect; /* if  has_indirect */
-                struct direct_storage direct;     /* if !has_indirect */
-        };
-
-        enum HashmapType type:2;     /* HASHMAP_TYPE_* */
-        bool has_indirect:1;         /* whether indirect storage is used */
-        unsigned n_direct_entries:3; /* Number of entries in direct storage.
-                                      * Only valid if !has_indirect. */
-        bool from_pool:1;            /* whether was allocated from mempool */
-        bool dirty:1;                /* whether dirtied since last iterated_cache_get() */
-        bool cached:1;               /* whether this hashmap is being cached */
-        HASHMAP_DEBUG_FIELDS         /* optional hashmap_debug_info */
-};
-
-/* Specific hash types
- * HashmapBase must be at the beginning of each hashmap struct. */
-
-struct Hashmap {
-        struct HashmapBase b;
-};
-
-struct OrderedHashmap {
-        struct HashmapBase b;
-        unsigned iterate_list_head, iterate_list_tail;
-};
-
-struct Set {
-        struct HashmapBase b;
-};
-
-typedef struct CacheMem {
-        const void **ptr;
-        size_t n_populated, n_allocated;
-        bool active:1;
-} CacheMem;
-
-struct IteratedCache {
-        HashmapBase *hashmap;
-        CacheMem keys, values;
-};
-
-DEFINE_MEMPOOL(hashmap_pool,         Hashmap,        8);
-DEFINE_MEMPOOL(ordered_hashmap_pool, OrderedHashmap, 8);
-/* No need for a separate Set pool */
-assert_cc(sizeof(Hashmap) == sizeof(Set));
-
-struct hashmap_type_info {
-        size_t head_size;
-        size_t entry_size;
-        struct mempool *mempool;
-        unsigned n_direct_buckets;
-};
-
-static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
-        [HASHMAP_TYPE_PLAIN] = {
-                .head_size        = sizeof(Hashmap),
-                .entry_size       = sizeof(struct plain_hashmap_entry),
-                .mempool          = &hashmap_pool,
-                .n_direct_buckets = DIRECT_BUCKETS(struct plain_hashmap_entry),
-        },
-        [HASHMAP_TYPE_ORDERED] = {
-                .head_size        = sizeof(OrderedHashmap),
-                .entry_size       = sizeof(struct ordered_hashmap_entry),
-                .mempool          = &ordered_hashmap_pool,
-                .n_direct_buckets = DIRECT_BUCKETS(struct ordered_hashmap_entry),
-        },
-        [HASHMAP_TYPE_SET] = {
-                .head_size        = sizeof(Set),
-                .entry_size       = sizeof(struct set_entry),
-                .mempool          = &hashmap_pool,
-                .n_direct_buckets = DIRECT_BUCKETS(struct set_entry),
-        },
-};
-
-#if VALGRIND
-__attribute__((destructor)) static void cleanup_pools(void) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        /* Be nice to valgrind */
-
-        /* The pool is only allocated by the main thread, but the memory can
-         * be passed to other threads. Let's clean up if we are the main thread
-         * and no other threads are live. */
-        if (!is_main_thread())
-                return;
-
-        r = get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t);
-        if (r < 0 || !streq(t, "1"))
-                return;
-
-        mempool_drop(&hashmap_pool);
-        mempool_drop(&ordered_hashmap_pool);
-}
-#endif
-
-static unsigned n_buckets(HashmapBase *h) {
-        return h->has_indirect ? h->indirect.n_buckets
-                               : hashmap_type_info[h->type].n_direct_buckets;
-}
-
-static unsigned n_entries(HashmapBase *h) {
-        return h->has_indirect ? h->indirect.n_entries
-                               : h->n_direct_entries;
-}
-
-static void n_entries_inc(HashmapBase *h) {
-        if (h->has_indirect)
-                h->indirect.n_entries++;
-        else
-                h->n_direct_entries++;
-}
-
-static void n_entries_dec(HashmapBase *h) {
-        if (h->has_indirect)
-                h->indirect.n_entries--;
-        else
-                h->n_direct_entries--;
-}
-
-static void *storage_ptr(HashmapBase *h) {
-        return h->has_indirect ? h->indirect.storage
-                               : h->direct.storage;
-}
-
-static uint8_t *hash_key(HashmapBase *h) {
-        return h->has_indirect ? h->indirect.hash_key
-                               : shared_hash_key;
-}
-
-static unsigned base_bucket_hash(HashmapBase *h, const void *p) {
-        struct siphash state;
-        uint64_t hash;
-
-        siphash24_init(&state, hash_key(h));
-
-        h->hash_ops->hash(p, &state);
-
-        hash = siphash24_finalize(&state);
-
-        return (unsigned) (hash % n_buckets(h));
-}
-#define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p)
-
-static inline void base_set_dirty(HashmapBase *h) {
-        h->dirty = true;
-}
-#define hashmap_set_dirty(h) base_set_dirty(HASHMAP_BASE(h))
-
-static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) {
-        static uint8_t current[HASH_KEY_SIZE];
-        static bool current_initialized = false;
-
-        /* Returns a hash function key to use. In order to keep things
-         * fast we will not generate a new key each time we allocate a
-         * new hash table. Instead, we'll just reuse the most recently
-         * generated one, except if we never generated one or when we
-         * are rehashing an entire hash table because we reached a
-         * fill level */
-
-        if (!current_initialized || !reuse_is_ok) {
-                random_bytes(current, sizeof(current));
-                current_initialized = true;
-        }
-
-        memcpy(hash_key, current, sizeof(current));
-}
-
-static struct hashmap_base_entry *bucket_at(HashmapBase *h, unsigned idx) {
-        return (struct hashmap_base_entry*)
-                ((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
-}
-
-static struct plain_hashmap_entry *plain_bucket_at(Hashmap *h, unsigned idx) {
-        return (struct plain_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx);
-}
-
-static struct ordered_hashmap_entry *ordered_bucket_at(OrderedHashmap *h, unsigned idx) {
-        return (struct ordered_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx);
-}
-
-static struct set_entry *set_bucket_at(Set *h, unsigned idx) {
-        return (struct set_entry*) bucket_at(HASHMAP_BASE(h), idx);
-}
-
-static struct ordered_hashmap_entry *bucket_at_swap(struct swap_entries *swap, unsigned idx) {
-        return &swap->e[idx - _IDX_SWAP_BEGIN];
-}
-
-/* Returns a pointer to the bucket at index idx.
- * Understands real indexes and swap indexes, hence "_virtual". */
-static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_entries *swap,
-                                                    unsigned idx) {
-        if (idx < _IDX_SWAP_BEGIN)
-                return bucket_at(h, idx);
-
-        if (idx < _IDX_SWAP_END)
-                return &bucket_at_swap(swap, idx)->p.b;
-
-        assert_not_reached("Invalid index");
-}
-
-static dib_raw_t *dib_raw_ptr(HashmapBase *h) {
-        return (dib_raw_t*)
-                ((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
-}
-
-static unsigned bucket_distance(HashmapBase *h, unsigned idx, unsigned from) {
-        return idx >= from ? idx - from
-                           : n_buckets(h) + idx - from;
-}
-
-static unsigned bucket_calculate_dib(HashmapBase *h, unsigned idx, dib_raw_t raw_dib) {
-        unsigned initial_bucket;
-
-        if (raw_dib == DIB_RAW_FREE)
-                return DIB_FREE;
-
-        if (_likely_(raw_dib < DIB_RAW_OVERFLOW))
-                return raw_dib;
-
-        /*
-         * Having an overflow DIB value is very unlikely. The hash function
-         * would have to be bad. For example, in a table of size 2^24 filled
-         * to load factor 0.9 the maximum observed DIB is only about 60.
-         * In theory (assuming I used Maxima correctly), for an infinite size
-         * hash table with load factor 0.8 the probability of a given entry
-         * having DIB > 40 is 1.9e-8.
-         * This returns the correct DIB value by recomputing the hash value in
-         * the unlikely case. XXX Hitting this case could be a hint to rehash.
-         */
-        initial_bucket = bucket_hash(h, bucket_at(h, idx)->key);
-        return bucket_distance(h, idx, initial_bucket);
-}
-
-static void bucket_set_dib(HashmapBase *h, unsigned idx, unsigned dib) {
-        dib_raw_ptr(h)[idx] = dib != DIB_FREE ? MIN(dib, DIB_RAW_OVERFLOW) : DIB_RAW_FREE;
-}
-
-static unsigned skip_free_buckets(HashmapBase *h, unsigned idx) {
-        dib_raw_t *dibs;
-
-        dibs = dib_raw_ptr(h);
-
-        for ( ; idx < n_buckets(h); idx++)
-                if (dibs[idx] != DIB_RAW_FREE)
-                        return idx;
-
-        return IDX_NIL;
-}
-
-static void bucket_mark_free(HashmapBase *h, unsigned idx) {
-        memzero(bucket_at(h, idx), hashmap_type_info[h->type].entry_size);
-        bucket_set_dib(h, idx, DIB_FREE);
-}
-
-static void bucket_move_entry(HashmapBase *h, struct swap_entries *swap,
-                              unsigned from, unsigned to) {
-        struct hashmap_base_entry *e_from, *e_to;
-
-        assert(from != to);
-
-        e_from = bucket_at_virtual(h, swap, from);
-        e_to   = bucket_at_virtual(h, swap, to);
-
-        memcpy(e_to, e_from, hashmap_type_info[h->type].entry_size);
-
-        if (h->type == HASHMAP_TYPE_ORDERED) {
-                OrderedHashmap *lh = (OrderedHashmap*) h;
-                struct ordered_hashmap_entry *le, *le_to;
-
-                le_to = (struct ordered_hashmap_entry*) e_to;
-
-                if (le_to->iterate_next != IDX_NIL) {
-                        le = (struct ordered_hashmap_entry*)
-                             bucket_at_virtual(h, swap, le_to->iterate_next);
-                        le->iterate_previous = to;
-                }
-
-                if (le_to->iterate_previous != IDX_NIL) {
-                        le = (struct ordered_hashmap_entry*)
-                             bucket_at_virtual(h, swap, le_to->iterate_previous);
-                        le->iterate_next = to;
-                }
-
-                if (lh->iterate_list_head == from)
-                        lh->iterate_list_head = to;
-                if (lh->iterate_list_tail == from)
-                        lh->iterate_list_tail = to;
-        }
-}
-
-static unsigned next_idx(HashmapBase *h, unsigned idx) {
-        return (idx + 1U) % n_buckets(h);
-}
-
-static unsigned prev_idx(HashmapBase *h, unsigned idx) {
-        return (n_buckets(h) + idx - 1U) % n_buckets(h);
-}
-
-static void *entry_value(HashmapBase *h, struct hashmap_base_entry *e) {
-        switch (h->type) {
-
-        case HASHMAP_TYPE_PLAIN:
-        case HASHMAP_TYPE_ORDERED:
-                return ((struct plain_hashmap_entry*)e)->value;
-
-        case HASHMAP_TYPE_SET:
-                return (void*) e->key;
-
-        default:
-                assert_not_reached("Unknown hashmap type");
-        }
-}
-
-static void base_remove_entry(HashmapBase *h, unsigned idx) {
-        unsigned left, right, prev, dib;
-        dib_raw_t raw_dib, *dibs;
-
-        dibs = dib_raw_ptr(h);
-        assert(dibs[idx] != DIB_RAW_FREE);
-
-#if ENABLE_DEBUG_HASHMAP
-        h->debug.rem_count++;
-        h->debug.last_rem_idx = idx;
-#endif
-
-        left = idx;
-        /* Find the stop bucket ("right"). It is either free or has DIB == 0. */
-        for (right = next_idx(h, left); ; right = next_idx(h, right)) {
-                raw_dib = dibs[right];
-                if (IN_SET(raw_dib, 0, DIB_RAW_FREE))
-                        break;
-
-                /* The buckets are not supposed to be all occupied and with DIB > 0.
-                 * That would mean we could make everyone better off by shifting them
-                 * backward. This scenario is impossible. */
-                assert(left != right);
-        }
-
-        if (h->type == HASHMAP_TYPE_ORDERED) {
-                OrderedHashmap *lh = (OrderedHashmap*) h;
-                struct ordered_hashmap_entry *le = ordered_bucket_at(lh, idx);
-
-                if (le->iterate_next != IDX_NIL)
-                        ordered_bucket_at(lh, le->iterate_next)->iterate_previous = le->iterate_previous;
-                else
-                        lh->iterate_list_tail = le->iterate_previous;
-
-                if (le->iterate_previous != IDX_NIL)
-                        ordered_bucket_at(lh, le->iterate_previous)->iterate_next = le->iterate_next;
-                else
-                        lh->iterate_list_head = le->iterate_next;
-        }
-
-        /* Now shift all buckets in the interval (left, right) one step backwards */
-        for (prev = left, left = next_idx(h, left); left != right;
-             prev = left, left = next_idx(h, left)) {
-                dib = bucket_calculate_dib(h, left, dibs[left]);
-                assert(dib != 0);
-                bucket_move_entry(h, NULL, left, prev);
-                bucket_set_dib(h, prev, dib - 1);
-        }
-
-        bucket_mark_free(h, prev);
-        n_entries_dec(h);
-        base_set_dirty(h);
-}
-#define remove_entry(h, idx) base_remove_entry(HASHMAP_BASE(h), idx)
-
-static unsigned hashmap_iterate_in_insertion_order(OrderedHashmap *h, Iterator *i) {
-        struct ordered_hashmap_entry *e;
-        unsigned idx;
-
-        assert(h);
-        assert(i);
-
-        if (i->idx == IDX_NIL)
-                goto at_end;
-
-        if (i->idx == IDX_FIRST && h->iterate_list_head == IDX_NIL)
-                goto at_end;
-
-        if (i->idx == IDX_FIRST) {
-                idx = h->iterate_list_head;
-                e = ordered_bucket_at(h, idx);
-        } else {
-                idx = i->idx;
-                e = ordered_bucket_at(h, idx);
-                /*
-                 * We allow removing the current entry while iterating, but removal may cause
-                 * a backward shift. The next entry may thus move one bucket to the left.
-                 * To detect when it happens, we remember the key pointer of the entry we were
-                 * going to iterate next. If it does not match, there was a backward shift.
-                 */
-                if (e->p.b.key != i->next_key) {
-                        idx = prev_idx(HASHMAP_BASE(h), idx);
-                        e = ordered_bucket_at(h, idx);
-                }
-                assert(e->p.b.key == i->next_key);
-        }
-
-#if ENABLE_DEBUG_HASHMAP
-        i->prev_idx = idx;
-#endif
-
-        if (e->iterate_next != IDX_NIL) {
-                struct ordered_hashmap_entry *n;
-                i->idx = e->iterate_next;
-                n = ordered_bucket_at(h, i->idx);
-                i->next_key = n->p.b.key;
-        } else
-                i->idx = IDX_NIL;
-
-        return idx;
-
-at_end:
-        i->idx = IDX_NIL;
-        return IDX_NIL;
-}
-
-static unsigned hashmap_iterate_in_internal_order(HashmapBase *h, Iterator *i) {
-        unsigned idx;
-
-        assert(h);
-        assert(i);
-
-        if (i->idx == IDX_NIL)
-                goto at_end;
-
-        if (i->idx == IDX_FIRST) {
-                /* fast forward to the first occupied bucket */
-                if (h->has_indirect) {
-                        i->idx = skip_free_buckets(h, h->indirect.idx_lowest_entry);
-                        h->indirect.idx_lowest_entry = i->idx;
-                } else
-                        i->idx = skip_free_buckets(h, 0);
-
-                if (i->idx == IDX_NIL)
-                        goto at_end;
-        } else {
-                struct hashmap_base_entry *e;
-
-                assert(i->idx > 0);
-
-                e = bucket_at(h, i->idx);
-                /*
-                 * We allow removing the current entry while iterating, but removal may cause
-                 * a backward shift. The next entry may thus move one bucket to the left.
-                 * To detect when it happens, we remember the key pointer of the entry we were
-                 * going to iterate next. If it does not match, there was a backward shift.
-                 */
-                if (e->key != i->next_key)
-                        e = bucket_at(h, --i->idx);
-
-                assert(e->key == i->next_key);
-        }
-
-        idx = i->idx;
-#if ENABLE_DEBUG_HASHMAP
-        i->prev_idx = idx;
-#endif
-
-        i->idx = skip_free_buckets(h, i->idx + 1);
-        if (i->idx != IDX_NIL)
-                i->next_key = bucket_at(h, i->idx)->key;
-        else
-                i->idx = IDX_NIL;
-
-        return idx;
-
-at_end:
-        i->idx = IDX_NIL;
-        return IDX_NIL;
-}
-
-static unsigned hashmap_iterate_entry(HashmapBase *h, Iterator *i) {
-        if (!h) {
-                i->idx = IDX_NIL;
-                return IDX_NIL;
-        }
-
-#if ENABLE_DEBUG_HASHMAP
-        if (i->idx == IDX_FIRST) {
-                i->put_count = h->debug.put_count;
-                i->rem_count = h->debug.rem_count;
-        } else {
-                /* While iterating, must not add any new entries */
-                assert(i->put_count == h->debug.put_count);
-                /* ... or remove entries other than the current one */
-                assert(i->rem_count == h->debug.rem_count ||
-                       (i->rem_count == h->debug.rem_count - 1 &&
-                        i->prev_idx == h->debug.last_rem_idx));
-                /* Reset our removals counter */
-                i->rem_count = h->debug.rem_count;
-        }
-#endif
-
-        return h->type == HASHMAP_TYPE_ORDERED ? hashmap_iterate_in_insertion_order((OrderedHashmap*) h, i)
-                                               : hashmap_iterate_in_internal_order(h, i);
-}
-
-bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key) {
-        struct hashmap_base_entry *e;
-        void *data;
-        unsigned idx;
-
-        idx = hashmap_iterate_entry(h, i);
-        if (idx == IDX_NIL) {
-                if (value)
-                        *value = NULL;
-                if (key)
-                        *key = NULL;
-
-                return false;
-        }
-
-        e = bucket_at(h, idx);
-        data = entry_value(h, e);
-        if (value)
-                *value = data;
-        if (key)
-                *key = e->key;
-
-        return true;
-}
-
-bool set_iterate(Set *s, Iterator *i, void **value) {
-        return internal_hashmap_iterate(HASHMAP_BASE(s), i, value, NULL);
-}
-
-#define HASHMAP_FOREACH_IDX(idx, h, i) \
-        for ((i) = ITERATOR_FIRST, (idx) = hashmap_iterate_entry((h), &(i)); \
-             (idx != IDX_NIL); \
-             (idx) = hashmap_iterate_entry((h), &(i)))
-
-IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h) {
-        IteratedCache *cache;
-
-        assert(h);
-        assert(!h->cached);
-
-        if (h->cached)
-                return NULL;
-
-        cache = new0(IteratedCache, 1);
-        if (!cache)
-                return NULL;
-
-        cache->hashmap = h;
-        h->cached = true;
-
-        return cache;
-}
-
-static void reset_direct_storage(HashmapBase *h) {
-        const struct hashmap_type_info *hi = &hashmap_type_info[h->type];
-        void *p;
-
-        assert(!h->has_indirect);
-
-        p = mempset(h->direct.storage, 0, hi->entry_size * hi->n_direct_buckets);
-        memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
-}
-
-static bool use_pool(void) {
-        static int b = -1;
-
-        if (!is_main_thread())
-                return false;
-
-        if (b < 0)
-                b = getenv_bool("SYSTEMD_MEMPOOL") != 0;
-
-        return b;
-}
-
-static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
-        HashmapBase *h;
-        const struct hashmap_type_info *hi = &hashmap_type_info[type];
-        bool up;
-
-        up = use_pool();
-
-        h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
-        if (!h)
-                return NULL;
-
-        h->type = type;
-        h->from_pool = up;
-        h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;
-
-        if (type == HASHMAP_TYPE_ORDERED) {
-                OrderedHashmap *lh = (OrderedHashmap*)h;
-                lh->iterate_list_head = lh->iterate_list_tail = IDX_NIL;
-        }
-
-        reset_direct_storage(h);
-
-        if (!shared_hash_key_initialized) {
-                random_bytes(shared_hash_key, sizeof(shared_hash_key));
-                shared_hash_key_initialized= true;
-        }
-
-#if ENABLE_DEBUG_HASHMAP
-        h->debug.func = func;
-        h->debug.file = file;
-        h->debug.line = line;
-        assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0);
-        LIST_PREPEND(debug_list, hashmap_debug_list, &h->debug);
-        assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
-#endif
-
-        return h;
-}
-
-Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (Hashmap*)        hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
-}
-
-OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
-}
-
-Set *internal_set_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (Set*)            hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
-}
-
-static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops *hash_ops,
-                                         enum HashmapType type HASHMAP_DEBUG_PARAMS) {
-        HashmapBase *q;
-
-        assert(h);
-
-        if (*h)
-                return 0;
-
-        q = hashmap_base_new(hash_ops, type HASHMAP_DEBUG_PASS_ARGS);
-        if (!q)
-                return -ENOMEM;
-
-        *h = q;
-        return 0;
-}
-
-int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
-}
-
-int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
-}
-
-int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
-}
-
-static void hashmap_free_no_clear(HashmapBase *h) {
-        assert(!h->has_indirect);
-        assert(!h->n_direct_entries);
-
-#if ENABLE_DEBUG_HASHMAP
-        assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0);
-        LIST_REMOVE(debug_list, hashmap_debug_list, &h->debug);
-        assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
-#endif
-
-        if (h->from_pool) {
-                /* Ensure that the object didn't get migrated between threads. */
-                assert_se(is_main_thread());
-                mempool_free_tile(hashmap_type_info[h->type].mempool, h);
-        } else
-                free(h);
-}
-
-HashmapBase *internal_hashmap_free(HashmapBase *h) {
-
-        /* Free the hashmap, but nothing in it */
-
-        if (h) {
-                internal_hashmap_clear(h);
-                hashmap_free_no_clear(h);
-        }
-
-        return NULL;
-}
-
-HashmapBase *internal_hashmap_free_free(HashmapBase *h) {
-
-        /* Free the hashmap and all data objects in it, but not the
-         * keys */
-
-        if (h) {
-                internal_hashmap_clear_free(h);
-                hashmap_free_no_clear(h);
-        }
-
-        return NULL;
-}
-
-Hashmap *hashmap_free_free_free(Hashmap *h) {
-
-        /* Free the hashmap and all data and key objects in it */
-
-        if (h) {
-                hashmap_clear_free_free(h);
-                hashmap_free_no_clear(HASHMAP_BASE(h));
-        }
-
-        return NULL;
-}
-
-void internal_hashmap_clear(HashmapBase *h) {
-        if (!h)
-                return;
-
-        if (h->has_indirect) {
-                free(h->indirect.storage);
-                h->has_indirect = false;
-        }
-
-        h->n_direct_entries = 0;
-        reset_direct_storage(h);
-
-        if (h->type == HASHMAP_TYPE_ORDERED) {
-                OrderedHashmap *lh = (OrderedHashmap*) h;
-                lh->iterate_list_head = lh->iterate_list_tail = IDX_NIL;
-        }
-
-        base_set_dirty(h);
-}
-
-void internal_hashmap_clear_free(HashmapBase *h) {
-        unsigned idx;
-
-        if (!h)
-                return;
-
-        for (idx = skip_free_buckets(h, 0); idx != IDX_NIL;
-             idx = skip_free_buckets(h, idx + 1))
-                free(entry_value(h, bucket_at(h, idx)));
-
-        internal_hashmap_clear(h);
-}
-
-void hashmap_clear_free_free(Hashmap *h) {
-        unsigned idx;
-
-        if (!h)
-                return;
-
-        for (idx = skip_free_buckets(HASHMAP_BASE(h), 0); idx != IDX_NIL;
-             idx = skip_free_buckets(HASHMAP_BASE(h), idx + 1)) {
-                struct plain_hashmap_entry *e = plain_bucket_at(h, idx);
-                free((void*)e->b.key);
-                free(e->value);
-        }
-
-        internal_hashmap_clear(HASHMAP_BASE(h));
-}
-
-static int resize_buckets(HashmapBase *h, unsigned entries_add);
-
-/*
- * Finds an empty bucket to put an entry into, starting the scan at 'idx'.
- * Performs Robin Hood swaps as it goes. The entry to put must be placed
- * by the caller into swap slot IDX_PUT.
- * If used for in-place resizing, may leave a displaced entry in swap slot
- * IDX_PUT. Caller must rehash it next.
- * Returns: true if it left a displaced entry to rehash next in IDX_PUT,
- *          false otherwise.
- */
-static bool hashmap_put_robin_hood(HashmapBase *h, unsigned idx,
-                                   struct swap_entries *swap) {
-        dib_raw_t raw_dib, *dibs;
-        unsigned dib, distance;
-
-#if ENABLE_DEBUG_HASHMAP
-        h->debug.put_count++;
-#endif
-
-        dibs = dib_raw_ptr(h);
-
-        for (distance = 0; ; distance++) {
-                raw_dib = dibs[idx];
-                if (IN_SET(raw_dib, DIB_RAW_FREE, DIB_RAW_REHASH)) {
-                        if (raw_dib == DIB_RAW_REHASH)
-                                bucket_move_entry(h, swap, idx, IDX_TMP);
-
-                        if (h->has_indirect && h->indirect.idx_lowest_entry > idx)
-                                h->indirect.idx_lowest_entry = idx;
-
-                        bucket_set_dib(h, idx, distance);
-                        bucket_move_entry(h, swap, IDX_PUT, idx);
-                        if (raw_dib == DIB_RAW_REHASH) {
-                                bucket_move_entry(h, swap, IDX_TMP, IDX_PUT);
-                                return true;
-                        }
-
-                        return false;
-                }
-
-                dib = bucket_calculate_dib(h, idx, raw_dib);
-
-                if (dib < distance) {
-                        /* Found a wealthier entry. Go Robin Hood! */
-                        bucket_set_dib(h, idx, distance);
-
-                        /* swap the entries */
-                        bucket_move_entry(h, swap, idx, IDX_TMP);
-                        bucket_move_entry(h, swap, IDX_PUT, idx);
-                        bucket_move_entry(h, swap, IDX_TMP, IDX_PUT);
-
-                        distance = dib;
-                }
-
-                idx = next_idx(h, idx);
-        }
-}
-
-/*
- * Puts an entry into a hashmap, boldly - no check whether key already exists.
- * The caller must place the entry (only its key and value, not link indexes)
- * in swap slot IDX_PUT.
- * Caller must ensure: the key does not exist yet in the hashmap.
- *                     that resize is not needed if !may_resize.
- * Returns: 1 if entry was put successfully.
- *          -ENOMEM if may_resize==true and resize failed with -ENOMEM.
- *          Cannot return -ENOMEM if !may_resize.
- */
-static int hashmap_base_put_boldly(HashmapBase *h, unsigned idx,
-                                   struct swap_entries *swap, bool may_resize) {
-        struct ordered_hashmap_entry *new_entry;
-        int r;
-
-        assert(idx < n_buckets(h));
-
-        new_entry = bucket_at_swap(swap, IDX_PUT);
-
-        if (may_resize) {
-                r = resize_buckets(h, 1);
-                if (r < 0)
-                        return r;
-                if (r > 0)
-                        idx = bucket_hash(h, new_entry->p.b.key);
-        }
-        assert(n_entries(h) < n_buckets(h));
-
-        if (h->type == HASHMAP_TYPE_ORDERED) {
-                OrderedHashmap *lh = (OrderedHashmap*) h;
-
-                new_entry->iterate_next = IDX_NIL;
-                new_entry->iterate_previous = lh->iterate_list_tail;
-
-                if (lh->iterate_list_tail != IDX_NIL) {
-                        struct ordered_hashmap_entry *old_tail;
-
-                        old_tail = ordered_bucket_at(lh, lh->iterate_list_tail);
-                        assert(old_tail->iterate_next == IDX_NIL);
-                        old_tail->iterate_next = IDX_PUT;
-                }
-
-                lh->iterate_list_tail = IDX_PUT;
-                if (lh->iterate_list_head == IDX_NIL)
-                        lh->iterate_list_head = IDX_PUT;
-        }
-
-        assert_se(hashmap_put_robin_hood(h, idx, swap) == false);
-
-        n_entries_inc(h);
-#if ENABLE_DEBUG_HASHMAP
-        h->debug.max_entries = MAX(h->debug.max_entries, n_entries(h));
-#endif
-
-        base_set_dirty(h);
-
-        return 1;
-}
-#define hashmap_put_boldly(h, idx, swap, may_resize) \
-        hashmap_base_put_boldly(HASHMAP_BASE(h), idx, swap, may_resize)
-
-/*
- * Returns 0 if resize is not needed.
- *         1 if successfully resized.
- *         -ENOMEM on allocation failure.
- */
-static int resize_buckets(HashmapBase *h, unsigned entries_add) {
-        struct swap_entries swap;
-        void *new_storage;
-        dib_raw_t *old_dibs, *new_dibs;
-        const struct hashmap_type_info *hi;
-        unsigned idx, optimal_idx;
-        unsigned old_n_buckets, new_n_buckets, n_rehashed, new_n_entries;
-        uint8_t new_shift;
-        bool rehash_next;
-
-        assert(h);
-
-        hi = &hashmap_type_info[h->type];
-        new_n_entries = n_entries(h) + entries_add;
-
-        /* overflow? */
-        if (_unlikely_(new_n_entries < entries_add))
-                return -ENOMEM;
-
-        /* For direct storage we allow 100% load, because it's tiny. */
-        if (!h->has_indirect && new_n_entries <= hi->n_direct_buckets)
-                return 0;
-
-        /*
-         * Load factor = n/m = 1 - (1/INV_KEEP_FREE).
-         * From it follows: m = n + n/(INV_KEEP_FREE - 1)
-         */
-        new_n_buckets = new_n_entries + new_n_entries / (INV_KEEP_FREE - 1);
-        /* overflow? */
-        if (_unlikely_(new_n_buckets < new_n_entries))
-                return -ENOMEM;
-
-        if (_unlikely_(new_n_buckets > UINT_MAX / (hi->entry_size + sizeof(dib_raw_t))))
-                return -ENOMEM;
-
-        old_n_buckets = n_buckets(h);
-
-        if (_likely_(new_n_buckets <= old_n_buckets))
-                return 0;
-
-        new_shift = log2u_round_up(MAX(
-                        new_n_buckets * (hi->entry_size + sizeof(dib_raw_t)),
-                        2 * sizeof(struct direct_storage)));
-
-        /* Realloc storage (buckets and DIB array). */
-        new_storage = realloc(h->has_indirect ? h->indirect.storage : NULL,
-                              1U << new_shift);
-        if (!new_storage)
-                return -ENOMEM;
-
-        /* Must upgrade direct to indirect storage. */
-        if (!h->has_indirect) {
-                memcpy(new_storage, h->direct.storage,
-                       old_n_buckets * (hi->entry_size + sizeof(dib_raw_t)));
-                h->indirect.n_entries = h->n_direct_entries;
-                h->indirect.idx_lowest_entry = 0;
-                h->n_direct_entries = 0;
-        }
-
-        /* Get a new hash key. If we've just upgraded to indirect storage,
-         * allow reusing a previously generated key. It's still a different key
-         * from the shared one that we used for direct storage. */
-        get_hash_key(h->indirect.hash_key, !h->has_indirect);
-
-        h->has_indirect = true;
-        h->indirect.storage = new_storage;
-        h->indirect.n_buckets = (1U << new_shift) /
-                                (hi->entry_size + sizeof(dib_raw_t));
-
-        old_dibs = (dib_raw_t*)((uint8_t*) new_storage + hi->entry_size * old_n_buckets);
-        new_dibs = dib_raw_ptr(h);
-
-        /*
-         * Move the DIB array to the new place, replacing valid DIB values with
-         * DIB_RAW_REHASH to indicate all of the used buckets need rehashing.
-         * Note: Overlap is not possible, because we have at least doubled the
-         * number of buckets and dib_raw_t is smaller than any entry type.
-         */
-        for (idx = 0; idx < old_n_buckets; idx++) {
-                assert(old_dibs[idx] != DIB_RAW_REHASH);
-                new_dibs[idx] = old_dibs[idx] == DIB_RAW_FREE ? DIB_RAW_FREE
-                                                              : DIB_RAW_REHASH;
-        }
-
-        /* Zero the area of newly added entries (including the old DIB area) */
-        memzero(bucket_at(h, old_n_buckets),
-               (n_buckets(h) - old_n_buckets) * hi->entry_size);
-
-        /* The upper half of the new DIB array needs initialization */
-        memset(&new_dibs[old_n_buckets], DIB_RAW_INIT,
-               (n_buckets(h) - old_n_buckets) * sizeof(dib_raw_t));
-
-        /* Rehash entries that need it */
-        n_rehashed = 0;
-        for (idx = 0; idx < old_n_buckets; idx++) {
-                if (new_dibs[idx] != DIB_RAW_REHASH)
-                        continue;
-
-                optimal_idx = bucket_hash(h, bucket_at(h, idx)->key);
-
-                /*
-                 * Not much to do if by luck the entry hashes to its current
-                 * location. Just set its DIB.
-                 */
-                if (optimal_idx == idx) {
-                        new_dibs[idx] = 0;
-                        n_rehashed++;
-                        continue;
-                }
-
-                new_dibs[idx] = DIB_RAW_FREE;
-                bucket_move_entry(h, &swap, idx, IDX_PUT);
-                /* bucket_move_entry does not clear the source */
-                memzero(bucket_at(h, idx), hi->entry_size);
-
-                do {
-                        /*
-                         * Find the new bucket for the current entry. This may make
-                         * another entry homeless and load it into IDX_PUT.
-                         */
-                        rehash_next = hashmap_put_robin_hood(h, optimal_idx, &swap);
-                        n_rehashed++;
-
-                        /* Did the current entry displace another one? */
-                        if (rehash_next)
-                                optimal_idx = bucket_hash(h, bucket_at_swap(&swap, IDX_PUT)->p.b.key);
-                } while (rehash_next);
-        }
-
-        assert(n_rehashed == n_entries(h));
-
-        return 1;
-}
-
-/*
- * Finds an entry with a matching key
- * Returns: index of the found entry, or IDX_NIL if not found.
- */
-static unsigned base_bucket_scan(HashmapBase *h, unsigned idx, const void *key) {
-        struct hashmap_base_entry *e;
-        unsigned dib, distance;
-        dib_raw_t *dibs = dib_raw_ptr(h);
-
-        assert(idx < n_buckets(h));
-
-        for (distance = 0; ; distance++) {
-                if (dibs[idx] == DIB_RAW_FREE)
-                        return IDX_NIL;
-
-                dib = bucket_calculate_dib(h, idx, dibs[idx]);
-
-                if (dib < distance)
-                        return IDX_NIL;
-                if (dib == distance) {
-                        e = bucket_at(h, idx);
-                        if (h->hash_ops->compare(e->key, key) == 0)
-                                return idx;
-                }
-
-                idx = next_idx(h, idx);
-        }
-}
-#define bucket_scan(h, idx, key) base_bucket_scan(HASHMAP_BASE(h), idx, key)
-
-int hashmap_put(Hashmap *h, const void *key, void *value) {
-        struct swap_entries swap;
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-
-        assert(h);
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx != IDX_NIL) {
-                e = plain_bucket_at(h, idx);
-                if (e->value == value)
-                        return 0;
-                return -EEXIST;
-        }
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p;
-        e->b.key = key;
-        e->value = value;
-        return hashmap_put_boldly(h, hash, &swap, true);
-}
-
-int set_put(Set *s, const void *key) {
-        struct swap_entries swap;
-        struct hashmap_base_entry *e;
-        unsigned hash, idx;
-
-        assert(s);
-
-        hash = bucket_hash(s, key);
-        idx = bucket_scan(s, hash, key);
-        if (idx != IDX_NIL)
-                return 0;
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p.b;
-        e->key = key;
-        return hashmap_put_boldly(s, hash, &swap, true);
-}
-
-int hashmap_replace(Hashmap *h, const void *key, void *value) {
-        struct swap_entries swap;
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-
-        assert(h);
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx != IDX_NIL) {
-                e = plain_bucket_at(h, idx);
-#if ENABLE_DEBUG_HASHMAP
-                /* Although the key is equal, the key pointer may have changed,
-                 * and this would break our assumption for iterating. So count
-                 * this operation as incompatible with iteration. */
-                if (e->b.key != key) {
-                        h->b.debug.put_count++;
-                        h->b.debug.rem_count++;
-                        h->b.debug.last_rem_idx = idx;
-                }
-#endif
-                e->b.key = key;
-                e->value = value;
-                hashmap_set_dirty(h);
-
-                return 0;
-        }
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p;
-        e->b.key = key;
-        e->value = value;
-        return hashmap_put_boldly(h, hash, &swap, true);
-}
-
-int hashmap_update(Hashmap *h, const void *key, void *value) {
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-
-        assert(h);
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return -ENOENT;
-
-        e = plain_bucket_at(h, idx);
-        e->value = value;
-        hashmap_set_dirty(h);
-
-        return 0;
-}
-
-void *internal_hashmap_get(HashmapBase *h, const void *key) {
-        struct hashmap_base_entry *e;
-        unsigned hash, idx;
-
-        if (!h)
-                return NULL;
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = bucket_at(h, idx);
-        return entry_value(h, e);
-}
-
-void *hashmap_get2(Hashmap *h, const void *key, void **key2) {
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-
-        if (!h)
-                return NULL;
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = plain_bucket_at(h, idx);
-        if (key2)
-                *key2 = (void*) e->b.key;
-
-        return e->value;
-}
-
-bool internal_hashmap_contains(HashmapBase *h, const void *key) {
-        unsigned hash;
-
-        if (!h)
-                return false;
-
-        hash = bucket_hash(h, key);
-        return bucket_scan(h, hash, key) != IDX_NIL;
-}
-
-void *internal_hashmap_remove(HashmapBase *h, const void *key) {
-        struct hashmap_base_entry *e;
-        unsigned hash, idx;
-        void *data;
-
-        if (!h)
-                return NULL;
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = bucket_at(h, idx);
-        data = entry_value(h, e);
-        remove_entry(h, idx);
-
-        return data;
-}
-
-void *hashmap_remove2(Hashmap *h, const void *key, void **rkey) {
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-        void *data;
-
-        if (!h) {
-                if (rkey)
-                        *rkey = NULL;
-                return NULL;
-        }
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL) {
-                if (rkey)
-                        *rkey = NULL;
-                return NULL;
-        }
-
-        e = plain_bucket_at(h, idx);
-        data = e->value;
-        if (rkey)
-                *rkey = (void*) e->b.key;
-
-        remove_entry(h, idx);
-
-        return data;
-}
-
-int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) {
-        struct swap_entries swap;
-        struct plain_hashmap_entry *e;
-        unsigned old_hash, new_hash, idx;
-
-        if (!h)
-                return -ENOENT;
-
-        old_hash = bucket_hash(h, old_key);
-        idx = bucket_scan(h, old_hash, old_key);
-        if (idx == IDX_NIL)
-                return -ENOENT;
-
-        new_hash = bucket_hash(h, new_key);
-        if (bucket_scan(h, new_hash, new_key) != IDX_NIL)
-                return -EEXIST;
-
-        remove_entry(h, idx);
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p;
-        e->b.key = new_key;
-        e->value = value;
-        assert_se(hashmap_put_boldly(h, new_hash, &swap, false) == 1);
-
-        return 0;
-}
-
-int set_remove_and_put(Set *s, const void *old_key, const void *new_key) {
-        struct swap_entries swap;
-        struct hashmap_base_entry *e;
-        unsigned old_hash, new_hash, idx;
-
-        if (!s)
-                return -ENOENT;
-
-        old_hash = bucket_hash(s, old_key);
-        idx = bucket_scan(s, old_hash, old_key);
-        if (idx == IDX_NIL)
-                return -ENOENT;
-
-        new_hash = bucket_hash(s, new_key);
-        if (bucket_scan(s, new_hash, new_key) != IDX_NIL)
-                return -EEXIST;
-
-        remove_entry(s, idx);
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p.b;
-        e->key = new_key;
-        assert_se(hashmap_put_boldly(s, new_hash, &swap, false) == 1);
-
-        return 0;
-}
-
-int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) {
-        struct swap_entries swap;
-        struct plain_hashmap_entry *e;
-        unsigned old_hash, new_hash, idx_old, idx_new;
-
-        if (!h)
-                return -ENOENT;
-
-        old_hash = bucket_hash(h, old_key);
-        idx_old = bucket_scan(h, old_hash, old_key);
-        if (idx_old == IDX_NIL)
-                return -ENOENT;
-
-        old_key = bucket_at(HASHMAP_BASE(h), idx_old)->key;
-
-        new_hash = bucket_hash(h, new_key);
-        idx_new = bucket_scan(h, new_hash, new_key);
-        if (idx_new != IDX_NIL)
-                if (idx_old != idx_new) {
-                        remove_entry(h, idx_new);
-                        /* Compensate for a possible backward shift. */
-                        if (old_key != bucket_at(HASHMAP_BASE(h), idx_old)->key)
-                                idx_old = prev_idx(HASHMAP_BASE(h), idx_old);
-                        assert(old_key == bucket_at(HASHMAP_BASE(h), idx_old)->key);
-                }
-
-        remove_entry(h, idx_old);
-
-        e = &bucket_at_swap(&swap, IDX_PUT)->p;
-        e->b.key = new_key;
-        e->value = value;
-        assert_se(hashmap_put_boldly(h, new_hash, &swap, false) == 1);
-
-        return 0;
-}
-
-void *hashmap_remove_value(Hashmap *h, const void *key, void *value) {
-        struct plain_hashmap_entry *e;
-        unsigned hash, idx;
-
-        if (!h)
-                return NULL;
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = plain_bucket_at(h, idx);
-        if (e->value != value)
-                return NULL;
-
-        remove_entry(h, idx);
-
-        return value;
-}
-
-static unsigned find_first_entry(HashmapBase *h) {
-        Iterator i = ITERATOR_FIRST;
-
-        if (!h || !n_entries(h))
-                return IDX_NIL;
-
-        return hashmap_iterate_entry(h, &i);
-}
-
-void *internal_hashmap_first(HashmapBase *h) {
-        unsigned idx;
-
-        idx = find_first_entry(h);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        return entry_value(h, bucket_at(h, idx));
-}
-
-void *internal_hashmap_first_key(HashmapBase *h) {
-        struct hashmap_base_entry *e;
-        unsigned idx;
-
-        idx = find_first_entry(h);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = bucket_at(h, idx);
-        return (void*) e->key;
-}
-
-void *internal_hashmap_steal_first(HashmapBase *h) {
-        struct hashmap_base_entry *e;
-        void *data;
-        unsigned idx;
-
-        idx = find_first_entry(h);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = bucket_at(h, idx);
-        data = entry_value(h, e);
-        remove_entry(h, idx);
-
-        return data;
-}
-
-void *internal_hashmap_steal_first_key(HashmapBase *h) {
-        struct hashmap_base_entry *e;
-        void *key;
-        unsigned idx;
-
-        idx = find_first_entry(h);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = bucket_at(h, idx);
-        key = (void*) e->key;
-        remove_entry(h, idx);
-
-        return key;
-}
-
-unsigned internal_hashmap_size(HashmapBase *h) {
-
-        if (!h)
-                return 0;
-
-        return n_entries(h);
-}
-
-unsigned internal_hashmap_buckets(HashmapBase *h) {
-
-        if (!h)
-                return 0;
-
-        return n_buckets(h);
-}
-
-int internal_hashmap_merge(Hashmap *h, Hashmap *other) {
-        Iterator i;
-        unsigned idx;
-
-        assert(h);
-
-        HASHMAP_FOREACH_IDX(idx, HASHMAP_BASE(other), i) {
-                struct plain_hashmap_entry *pe = plain_bucket_at(other, idx);
-                int r;
-
-                r = hashmap_put(h, pe->b.key, pe->value);
-                if (r < 0 && r != -EEXIST)
-                        return r;
-        }
-
-        return 0;
-}
-
-int set_merge(Set *s, Set *other) {
-        Iterator i;
-        unsigned idx;
-
-        assert(s);
-
-        HASHMAP_FOREACH_IDX(idx, HASHMAP_BASE(other), i) {
-                struct set_entry *se = set_bucket_at(other, idx);
-                int r;
-
-                r = set_put(s, se->b.key);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
-}
-
-int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add) {
-        int r;
-
-        assert(h);
-
-        r = resize_buckets(h, entries_add);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-/*
- * The same as hashmap_merge(), but every new item from other is moved to h.
- * Keys already in h are skipped and stay in other.
- * Returns: 0 on success.
- *          -ENOMEM on alloc failure, in which case no move has been done.
- */
-int internal_hashmap_move(HashmapBase *h, HashmapBase *other) {
-        struct swap_entries swap;
-        struct hashmap_base_entry *e, *n;
-        Iterator i;
-        unsigned idx;
-        int r;
-
-        assert(h);
-
-        if (!other)
-                return 0;
-
-        assert(other->type == h->type);
-
-        /*
-         * This reserves buckets for the worst case, where none of other's
-         * entries are yet present in h. This is preferable to risking
-         * an allocation failure in the middle of the moving and having to
-         * rollback or return a partial result.
-         */
-        r = resize_buckets(h, n_entries(other));
-        if (r < 0)
-                return r;
-
-        HASHMAP_FOREACH_IDX(idx, other, i) {
-                unsigned h_hash;
-
-                e = bucket_at(other, idx);
-                h_hash = bucket_hash(h, e->key);
-                if (bucket_scan(h, h_hash, e->key) != IDX_NIL)
-                        continue;
-
-                n = &bucket_at_swap(&swap, IDX_PUT)->p.b;
-                n->key = e->key;
-                if (h->type != HASHMAP_TYPE_SET)
-                        ((struct plain_hashmap_entry*) n)->value =
-                                ((struct plain_hashmap_entry*) e)->value;
-                assert_se(hashmap_put_boldly(h, h_hash, &swap, false) == 1);
-
-                remove_entry(other, idx);
-        }
-
-        return 0;
-}
-
-int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
-        struct swap_entries swap;
-        unsigned h_hash, other_hash, idx;
-        struct hashmap_base_entry *e, *n;
-        int r;
-
-        assert(h);
-
-        h_hash = bucket_hash(h, key);
-        if (bucket_scan(h, h_hash, key) != IDX_NIL)
-                return -EEXIST;
-
-        if (!other)
-                return -ENOENT;
-
-        assert(other->type == h->type);
-
-        other_hash = bucket_hash(other, key);
-        idx = bucket_scan(other, other_hash, key);
-        if (idx == IDX_NIL)
-                return -ENOENT;
-
-        e = bucket_at(other, idx);
-
-        n = &bucket_at_swap(&swap, IDX_PUT)->p.b;
-        n->key = e->key;
-        if (h->type != HASHMAP_TYPE_SET)
-                ((struct plain_hashmap_entry*) n)->value =
-                        ((struct plain_hashmap_entry*) e)->value;
-        r = hashmap_put_boldly(h, h_hash, &swap, true);
-        if (r < 0)
-                return r;
-
-        remove_entry(other, idx);
-        return 0;
-}
-
-HashmapBase *internal_hashmap_copy(HashmapBase *h) {
-        HashmapBase *copy;
-        int r;
-
-        assert(h);
-
-        copy = hashmap_base_new(h->hash_ops, h->type  HASHMAP_DEBUG_SRC_ARGS);
-        if (!copy)
-                return NULL;
-
-        switch (h->type) {
-        case HASHMAP_TYPE_PLAIN:
-        case HASHMAP_TYPE_ORDERED:
-                r = hashmap_merge((Hashmap*)copy, (Hashmap*)h);
-                break;
-        case HASHMAP_TYPE_SET:
-                r = set_merge((Set*)copy, (Set*)h);
-                break;
-        default:
-                assert_not_reached("Unknown hashmap type");
-        }
-
-        if (r < 0) {
-                internal_hashmap_free(copy);
-                return NULL;
-        }
-
-        return copy;
-}
-
-char **internal_hashmap_get_strv(HashmapBase *h) {
-        char **sv;
-        Iterator i;
-        unsigned idx, n;
-
-        sv = new(char*, n_entries(h)+1);
-        if (!sv)
-                return NULL;
-
-        n = 0;
-        HASHMAP_FOREACH_IDX(idx, h, i)
-                sv[n++] = entry_value(h, bucket_at(h, idx));
-        sv[n] = NULL;
-
-        return sv;
-}
-
-void *ordered_hashmap_next(OrderedHashmap *h, const void *key) {
-        struct ordered_hashmap_entry *e;
-        unsigned hash, idx;
-
-        if (!h)
-                return NULL;
-
-        hash = bucket_hash(h, key);
-        idx = bucket_scan(h, hash, key);
-        if (idx == IDX_NIL)
-                return NULL;
-
-        e = ordered_bucket_at(h, idx);
-        if (e->iterate_next == IDX_NIL)
-                return NULL;
-        return ordered_bucket_at(h, e->iterate_next)->p.value;
-}
-
-int set_consume(Set *s, void *value) {
-        int r;
-
-        assert(s);
-        assert(value);
-
-        r = set_put(s, value);
-        if (r <= 0)
-                free(value);
-
-        return r;
-}
-
-int set_put_strdup(Set *s, const char *p) {
-        char *c;
-
-        assert(s);
-        assert(p);
-
-        if (set_contains(s, (char*) p))
-                return 0;
-
-        c = strdup(p);
-        if (!c)
-                return -ENOMEM;
-
-        return set_consume(s, c);
-}
-
-int set_put_strdupv(Set *s, char **l) {
-        int n = 0, r;
-        char **i;
-
-        assert(s);
-
-        STRV_FOREACH(i, l) {
-                r = set_put_strdup(s, *i);
-                if (r < 0)
-                        return r;
-
-                n += r;
-        }
-
-        return n;
-}
-
-int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags) {
-        const char *p = v;
-        int r;
-
-        assert(s);
-        assert(v);
-
-        for (;;) {
-                char *word;
-
-                r = extract_first_word(&p, &word, separators, flags);
-                if (r <= 0)
-                        return r;
-
-                r = set_consume(s, word);
-                if (r < 0)
-                        return r;
-        }
-}
-
-/* expand the cachemem if needed, return true if newly (re)activated. */
-static int cachemem_maintain(CacheMem *mem, unsigned size) {
-        assert(mem);
-
-        if (!GREEDY_REALLOC(mem->ptr, mem->n_allocated, size)) {
-                if (size > 0)
-                        return -ENOMEM;
-        }
-
-        if (!mem->active) {
-                mem->active = true;
-                return true;
-        }
-
-        return false;
-}
-
-int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries) {
-        bool sync_keys = false, sync_values = false;
-        unsigned size;
-        int r;
-
-        assert(cache);
-        assert(cache->hashmap);
-
-        size = n_entries(cache->hashmap);
-
-        if (res_keys) {
-                r = cachemem_maintain(&cache->keys, size);
-                if (r < 0)
-                        return r;
-
-                sync_keys = r;
-        } else
-                cache->keys.active = false;
-
-        if (res_values) {
-                r = cachemem_maintain(&cache->values, size);
-                if (r < 0)
-                        return r;
-
-                sync_values = r;
-        } else
-                cache->values.active = false;
-
-        if (cache->hashmap->dirty) {
-                if (cache->keys.active)
-                        sync_keys = true;
-                if (cache->values.active)
-                        sync_values = true;
-
-                cache->hashmap->dirty = false;
-        }
-
-        if (sync_keys || sync_values) {
-                unsigned i, idx;
-                Iterator iter;
-
-                i = 0;
-                HASHMAP_FOREACH_IDX(idx, cache->hashmap, iter) {
-                        struct hashmap_base_entry *e;
-
-                        e = bucket_at(cache->hashmap, idx);
-
-                        if (sync_keys)
-                                cache->keys.ptr[i] = e->key;
-                        if (sync_values)
-                                cache->values.ptr[i] = entry_value(cache->hashmap, e);
-                        i++;
-                }
-        }
-
-        if (res_keys)
-                *res_keys = cache->keys.ptr;
-        if (res_values)
-                *res_values = cache->values.ptr;
-        if (res_n_entries)
-                *res_n_entries = size;
-
-        return 0;
-}
-
-IteratedCache *iterated_cache_free(IteratedCache *cache) {
-        if (cache) {
-                free(cache->keys.ptr);
-                free(cache->values.ptr);
-                free(cache);
-        }
-
-        return NULL;
-}
diff --git a/src/systemd/src/basic/hashmap.h b/src/systemd/src/basic/hashmap.h
deleted file mode 100644
index 274afb39..00000000
--- a/src/systemd/src/basic/hashmap.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <limits.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#include "hash-funcs.h"
-#include "macro.h"
-#include "util.h"
-
-/*
- * A hash table implementation. As a minor optimization a NULL hashmap object
- * will be treated as empty hashmap for all read operations. That way it is not
- * necessary to instantiate an object for each Hashmap use.
- *
- * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
- * the implemention will:
- * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
- * - perform extra checks for invalid use of iterators
- */
-
-#define HASH_KEY_SIZE 16
-
-/* The base type for all hashmap and set types. Many functions in the
- * implementation take (HashmapBase*) parameters and are run-time polymorphic,
- * though the API is not meant to be polymorphic (do not call functions
- * internal_*() directly). */
-typedef struct HashmapBase HashmapBase;
-
-/* Specific hashmap/set types */
-typedef struct Hashmap Hashmap;               /* Maps keys to values */
-typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */
-typedef struct Set Set;                       /* Stores just keys */
-
-typedef struct IteratedCache IteratedCache;   /* Caches the iterated order of one of the above */
-
-/* Ideally the Iterator would be an opaque struct, but it is instantiated
- * 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 */
-#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 */
-        unsigned prev_idx;    /* idx in previous iteration */
-#endif
-} Iterator;
-
-#define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
-#define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
-
-/* Macros for type checking */
-#define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \
-        (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \
-         __builtin_types_compatible_p(typeof(h), Hashmap*) || \
-         __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \
-         __builtin_types_compatible_p(typeof(h), Set*))
-
-#define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \
-        (__builtin_types_compatible_p(typeof(h), Hashmap*) || \
-         __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \
-
-#define HASHMAP_BASE(h) \
-        __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \
-                (HashmapBase*)(h), \
-                (void)0)
-
-#define PLAIN_HASHMAP(h) \
-        __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \
-                (Hashmap*)(h), \
-                (void)0)
-
-#if ENABLE_DEBUG_HASHMAP
-# define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
-# define HASHMAP_DEBUG_SRC_ARGS   , __func__, __FILE__, __LINE__
-# define HASHMAP_DEBUG_PASS_ARGS   , func, file, line
-#else
-# define HASHMAP_DEBUG_PARAMS
-# define HASHMAP_DEBUG_SRC_ARGS
-# define HASHMAP_DEBUG_PASS_ARGS
-#endif
-
-Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
-OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
-#define hashmap_new(ops) internal_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
-#define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
-
-HashmapBase *internal_hashmap_free(HashmapBase *h);
-static inline Hashmap *hashmap_free(Hashmap *h) {
-        return (void*)internal_hashmap_free(HASHMAP_BASE(h));
-}
-static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
-        return (void*)internal_hashmap_free(HASHMAP_BASE(h));
-}
-
-HashmapBase *internal_hashmap_free_free(HashmapBase *h);
-static inline Hashmap *hashmap_free_free(Hashmap *h) {
-        return (void*)internal_hashmap_free_free(HASHMAP_BASE(h));
-}
-static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
-        return (void*)internal_hashmap_free_free(HASHMAP_BASE(h));
-}
-
-Hashmap *hashmap_free_free_free(Hashmap *h);
-static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
-        return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h));
-}
-
-IteratedCache *iterated_cache_free(IteratedCache *cache);
-int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
-
-HashmapBase *internal_hashmap_copy(HashmapBase *h);
-static inline Hashmap *hashmap_copy(Hashmap *h) {
-        return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
-}
-static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
-        return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
-}
-
-int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
-int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
-#define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
-#define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
-
-IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h);
-static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
-        return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
-}
-static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
-        return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
-}
-
-int hashmap_put(Hashmap *h, const void *key, void *value);
-static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
-        return hashmap_put(PLAIN_HASHMAP(h), key, value);
-}
-
-int hashmap_update(Hashmap *h, const void *key, void *value);
-static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
-        return hashmap_update(PLAIN_HASHMAP(h), key, value);
-}
-
-int hashmap_replace(Hashmap *h, const void *key, void *value);
-static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
-        return hashmap_replace(PLAIN_HASHMAP(h), key, value);
-}
-
-void *internal_hashmap_get(HashmapBase *h, const void *key);
-static inline void *hashmap_get(Hashmap *h, const void *key) {
-        return internal_hashmap_get(HASHMAP_BASE(h), key);
-}
-static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
-        return internal_hashmap_get(HASHMAP_BASE(h), key);
-}
-
-void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
-static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
-        return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
-}
-
-bool internal_hashmap_contains(HashmapBase *h, const void *key);
-static inline bool hashmap_contains(Hashmap *h, const void *key) {
-        return internal_hashmap_contains(HASHMAP_BASE(h), key);
-}
-static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
-        return internal_hashmap_contains(HASHMAP_BASE(h), key);
-}
-
-void *internal_hashmap_remove(HashmapBase *h, const void *key);
-static inline void *hashmap_remove(Hashmap *h, const void *key) {
-        return internal_hashmap_remove(HASHMAP_BASE(h), key);
-}
-static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
-        return internal_hashmap_remove(HASHMAP_BASE(h), key);
-}
-
-void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
-static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
-        return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
-}
-
-void *hashmap_remove_value(Hashmap *h, const void *key, void *value);
-static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
-        return hashmap_remove_value(PLAIN_HASHMAP(h), key, value);
-}
-
-int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
-static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
-        return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value);
-}
-
-int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
-static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
-        return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value);
-}
-
-/* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
- * should just work, allow this by having looser type-checking here. */
-int internal_hashmap_merge(Hashmap *h, Hashmap *other);
-#define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
-#define ordered_hashmap_merge(h, other) hashmap_merge(h, other)
-
-int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
-static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
-        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
-}
-static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
-        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
-}
-
-int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
-/* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
-static inline int hashmap_move(Hashmap *h, Hashmap *other) {
-        return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
-}
-static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
-        return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
-}
-
-int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
-static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
-        return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
-}
-static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
-        return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
-}
-
-unsigned internal_hashmap_size(HashmapBase *h) _pure_;
-static inline unsigned hashmap_size(Hashmap *h) {
-        return internal_hashmap_size(HASHMAP_BASE(h));
-}
-static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
-        return internal_hashmap_size(HASHMAP_BASE(h));
-}
-
-static inline bool hashmap_isempty(Hashmap *h) {
-        return hashmap_size(h) == 0;
-}
-static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
-        return ordered_hashmap_size(h) == 0;
-}
-
-unsigned internal_hashmap_buckets(HashmapBase *h) _pure_;
-static inline unsigned hashmap_buckets(Hashmap *h) {
-        return internal_hashmap_buckets(HASHMAP_BASE(h));
-}
-static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
-        return internal_hashmap_buckets(HASHMAP_BASE(h));
-}
-
-bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
-static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
-        return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
-}
-static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
-        return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
-}
-
-void internal_hashmap_clear(HashmapBase *h);
-static inline void hashmap_clear(Hashmap *h) {
-        internal_hashmap_clear(HASHMAP_BASE(h));
-}
-static inline void ordered_hashmap_clear(OrderedHashmap *h) {
-        internal_hashmap_clear(HASHMAP_BASE(h));
-}
-
-void internal_hashmap_clear_free(HashmapBase *h);
-static inline void hashmap_clear_free(Hashmap *h) {
-        internal_hashmap_clear_free(HASHMAP_BASE(h));
-}
-static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
-        internal_hashmap_clear_free(HASHMAP_BASE(h));
-}
-
-void hashmap_clear_free_free(Hashmap *h);
-static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
-        hashmap_clear_free_free(PLAIN_HASHMAP(h));
-}
-
-/*
- * Note about all *_first*() functions
- *
- * For plain Hashmaps and Sets the order of entries is undefined.
- * The functions find whatever entry is first in the implementation
- * internal order.
- *
- * Only for OrderedHashmaps the order is well defined and finding
- * the first entry is O(1).
- */
-
-void *internal_hashmap_steal_first(HashmapBase *h);
-static inline void *hashmap_steal_first(Hashmap *h) {
-        return internal_hashmap_steal_first(HASHMAP_BASE(h));
-}
-static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
-        return internal_hashmap_steal_first(HASHMAP_BASE(h));
-}
-
-void *internal_hashmap_steal_first_key(HashmapBase *h);
-static inline void *hashmap_steal_first_key(Hashmap *h) {
-        return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
-}
-static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
-        return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
-}
-
-void *internal_hashmap_first_key(HashmapBase *h) _pure_;
-static inline void *hashmap_first_key(Hashmap *h) {
-        return internal_hashmap_first_key(HASHMAP_BASE(h));
-}
-static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
-        return internal_hashmap_first_key(HASHMAP_BASE(h));
-}
-
-void *internal_hashmap_first(HashmapBase *h) _pure_;
-static inline void *hashmap_first(Hashmap *h) {
-        return internal_hashmap_first(HASHMAP_BASE(h));
-}
-static inline void *ordered_hashmap_first(OrderedHashmap *h) {
-        return internal_hashmap_first(HASHMAP_BASE(h));
-}
-
-#define hashmap_clear_with_destructor(_s, _f)                   \
-        ({                                                      \
-                void *_item;                                    \
-                while ((_item = hashmap_steal_first(_s)))       \
-                        _f(_item);                              \
-        })
-#define hashmap_free_with_destructor(_s, _f)                    \
-        ({                                                      \
-                hashmap_clear_with_destructor(_s, _f);          \
-                hashmap_free(_s);                               \
-        })
-#define ordered_hashmap_clear_with_destructor(_s, _f)                   \
-        ({                                                              \
-                void *_item;                                            \
-                while ((_item = ordered_hashmap_steal_first(_s)))       \
-                        _f(_item);                                      \
-        })
-#define ordered_hashmap_free_with_destructor(_s, _f)                    \
-        ({                                                              \
-                ordered_hashmap_clear_with_destructor(_s, _f);          \
-                ordered_hashmap_free(_s);                               \
-        })
-
-/* no hashmap_next */
-void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
-
-char **internal_hashmap_get_strv(HashmapBase *h);
-static inline char **hashmap_get_strv(Hashmap *h) {
-        return internal_hashmap_get_strv(HASHMAP_BASE(h));
-}
-static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
-        return internal_hashmap_get_strv(HASHMAP_BASE(h));
-}
-
-/*
- * Hashmaps are iterated in unpredictable order.
- * OrderedHashmaps are an exception to this. They are iterated in the order
- * the entries were inserted.
- * It is safe to remove the current entry.
- */
-#define HASHMAP_FOREACH(e, h, i) \
-        for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
-
-#define ORDERED_HASHMAP_FOREACH(e, h, i) \
-        for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
-
-#define HASHMAP_FOREACH_KEY(e, k, h, i) \
-        for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
-
-#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
-        for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
-
-#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
-#define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
-#define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
-#define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep)
-#define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep)
-#define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep)
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(IteratedCache*, iterated_cache_free);
-
-#define _cleanup_iterated_cache_free_ _cleanup_(iterated_cache_freep)
diff --git a/src/systemd/src/basic/hexdecoct.c b/src/systemd/src/basic/hexdecoct.c
deleted file mode 100644
index 09f2a9e7..00000000
--- a/src/systemd/src/basic/hexdecoct.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "alloc-util.h"
-#include "hexdecoct.h"
-#include "macro.h"
-#include "string-util.h"
-#include "util.h"
-
-char octchar(int x) {
-        return '0' + (x & 7);
-}
-
-int unoctchar(char c) {
-
-        if (c >= '0' && c <= '7')
-                return c - '0';
-
-        return -EINVAL;
-}
-
-char decchar(int x) {
-        return '0' + (x % 10);
-}
-
-int undecchar(char c) {
-
-        if (c >= '0' && c <= '9')
-                return c - '0';
-
-        return -EINVAL;
-}
-
-char hexchar(int x) {
-        static const char table[16] = "0123456789abcdef";
-
-        return table[x & 15];
-}
-
-int unhexchar(char c) {
-
-        if (c >= '0' && c <= '9')
-                return c - '0';
-
-        if (c >= 'a' && c <= 'f')
-                return c - 'a' + 10;
-
-        if (c >= 'A' && c <= 'F')
-                return c - 'A' + 10;
-
-        return -EINVAL;
-}
-
-char *hexmem(const void *p, size_t l) {
-        const uint8_t *x;
-        char *r, *z;
-
-        z = r = new(char, l * 2 + 1);
-        if (!r)
-                return NULL;
-
-        for (x = p; x < (const uint8_t*) p + l; x++) {
-                *(z++) = hexchar(*x >> 4);
-                *(z++) = hexchar(*x & 15);
-        }
-
-        *z = 0;
-        return r;
-}
-
-static int unhex_next(const char **p, size_t *l) {
-        int r;
-
-        assert(p);
-        assert(l);
-
-        /* Find the next non-whitespace character, and decode it. We
-         * greedily skip all preceeding and all following whitespace. */
-
-        for (;;) {
-                if (*l == 0)
-                        return -EPIPE;
-
-                if (!strchr(WHITESPACE, **p))
-                        break;
-
-                /* Skip leading whitespace */
-                (*p)++, (*l)--;
-        }
-
-        r = unhexchar(**p);
-        if (r < 0)
-                return r;
-
-        for (;;) {
-                (*p)++, (*l)--;
-
-                if (*l == 0 || !strchr(WHITESPACE, **p))
-                        break;
-
-                /* Skip following whitespace */
-        }
-
-        return r;
-}
-
-int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
-        _cleanup_free_ uint8_t *buf = NULL;
-        const char *x;
-        uint8_t *z;
-
-        assert(ret);
-        assert(ret_len);
-        assert(p || l == 0);
-
-        if (l == (size_t) -1)
-                l = strlen(p);
-
-        /* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */
-        buf = malloc((l + 1) / 2 + 1);
-        if (!buf)
-                return -ENOMEM;
-
-        for (x = p, z = buf;;) {
-                int a, b;
-
-                a = unhex_next(&x, &l);
-                if (a == -EPIPE) /* End of string */
-                        break;
-                if (a < 0)
-                        return a;
-
-                b = unhex_next(&x, &l);
-                if (b < 0)
-                        return b;
-
-                *(z++) = (uint8_t) a << 4 | (uint8_t) b;
-        }
-
-        *z = 0;
-
-        *ret_len = (size_t) (z - buf);
-        *ret = TAKE_PTR(buf);
-
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-/* https://tools.ietf.org/html/rfc4648#section-6
- * Notice that base32hex differs from base32 in the alphabet it uses.
- * The distinction is that the base32hex representation preserves the
- * order of the underlying data when compared as bytestrings, this is
- * useful when representing NSEC3 hashes, as one can then verify the
- * order of hashes directly from their representation. */
-char base32hexchar(int x) {
-        static const char table[32] = "0123456789"
-                                      "ABCDEFGHIJKLMNOPQRSTUV";
-
-        return table[x & 31];
-}
-
-int unbase32hexchar(char c) {
-        unsigned offset;
-
-        if (c >= '0' && c <= '9')
-                return c - '0';
-
-        offset = '9' - '0' + 1;
-
-        if (c >= 'A' && c <= 'V')
-                return c - 'A' + offset;
-
-        return -EINVAL;
-}
-
-char *base32hexmem(const void *p, size_t l, bool padding) {
-        char *r, *z;
-        const uint8_t *x;
-        size_t len;
-
-        assert(p || l == 0);
-
-        if (padding)
-                /* five input bytes makes eight output bytes, padding is added so we must round up */
-                len = 8 * (l + 4) / 5;
-        else {
-                /* same, but round down as there is no padding */
-                len = 8 * l / 5;
-
-                switch (l % 5) {
-                case 4:
-                        len += 7;
-                        break;
-                case 3:
-                        len += 5;
-                        break;
-                case 2:
-                        len += 4;
-                        break;
-                case 1:
-                        len += 2;
-                        break;
-                }
-        }
-
-        z = r = malloc(len + 1);
-        if (!r)
-                return NULL;
-
-        for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
-                /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
-                 * x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
-                *(z++) = base32hexchar(x[0] >> 3);                    /* 000XXXXX */
-                *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6);  /* 000XXXYY */
-                *(z++) = base32hexchar((x[1] & 63) >> 1);             /* 000YYYYY */
-                *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4);  /* 000YZZZZ */
-                *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
-                *(z++) = base32hexchar((x[3] & 127) >> 2);            /* 000QQQQQ */
-                *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5);  /* 000QQWWW */
-                *(z++) = base32hexchar((x[4] & 31));                  /* 000WWWWW */
-        }
-
-        switch (l % 5) {
-        case 4:
-                *(z++) = base32hexchar(x[0] >> 3);                    /* 000XXXXX */
-                *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6);  /* 000XXXYY */
-                *(z++) = base32hexchar((x[1] & 63) >> 1);             /* 000YYYYY */
-                *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4);   /* 000YZZZZ */
-                *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
-                *(z++) = base32hexchar((x[3] & 127) >> 2);            /* 000QQQQQ */
-                *(z++) = base32hexchar((x[3] & 3) << 3);              /* 000QQ000 */
-                if (padding)
-                        *(z++) = '=';
-
-                break;
-
-        case 3:
-                *(z++) = base32hexchar(x[0] >> 3);                   /* 000XXXXX */
-                *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
-                *(z++) = base32hexchar((x[1] & 63) >> 1);            /* 000YYYYY */
-                *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
-                *(z++) = base32hexchar((x[2] & 15) << 1);            /* 000ZZZZ0 */
-                if (padding) {
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                }
-
-                break;
-
-        case 2:
-                *(z++) = base32hexchar(x[0] >> 3);                   /* 000XXXXX */
-                *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
-                *(z++) = base32hexchar((x[1] & 63) >> 1);            /* 000YYYYY */
-                *(z++) = base32hexchar((x[1] & 1) << 4);             /* 000Y0000 */
-                if (padding) {
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                }
-
-                break;
-
-        case 1:
-                *(z++) = base32hexchar(x[0] >> 3);       /* 000XXXXX */
-                *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
-                if (padding) {
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                        *(z++) = '=';
-                }
-
-                break;
-        }
-
-        *z = 0;
-        return r;
-}
-
-int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
-        _cleanup_free_ uint8_t *r = NULL;
-        int a, b, c, d, e, f, g, h;
-        uint8_t *z;
-        const char *x;
-        size_t len;
-        unsigned pad = 0;
-
-        assert(p || l == 0);
-        assert(mem);
-        assert(_len);
-
-        if (l == (size_t) -1)
-                l = strlen(p);
-
-        /* padding ensures any base32hex input has input divisible by 8 */
-        if (padding && l % 8 != 0)
-                return -EINVAL;
-
-        if (padding) {
-                /* strip the padding */
-                while (l > 0 && p[l - 1] == '=' && pad < 7) {
-                        pad++;
-                        l--;
-                }
-        }
-
-        /* a group of eight input bytes needs five output bytes, in case of
-         * padding we need to add some extra bytes */
-        len = (l / 8) * 5;
-
-        switch (l % 8) {
-        case 7:
-                len += 4;
-                break;
-        case 5:
-                len += 3;
-                break;
-        case 4:
-                len += 2;
-                break;
-        case 2:
-                len += 1;
-                break;
-        case 0:
-                break;
-        default:
-                return -EINVAL;
-        }
-
-        z = r = malloc(len + 1);
-        if (!r)
-                return -ENOMEM;
-
-        for (x = p; x < p + (l / 8) * 8; x += 8) {
-                /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
-                 * e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
-                a = unbase32hexchar(x[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unbase32hexchar(x[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                c = unbase32hexchar(x[2]);
-                if (c < 0)
-                        return -EINVAL;
-
-                d = unbase32hexchar(x[3]);
-                if (d < 0)
-                        return -EINVAL;
-
-                e = unbase32hexchar(x[4]);
-                if (e < 0)
-                        return -EINVAL;
-
-                f = unbase32hexchar(x[5]);
-                if (f < 0)
-                        return -EINVAL;
-
-                g = unbase32hexchar(x[6]);
-                if (g < 0)
-                        return -EINVAL;
-
-                h = unbase32hexchar(x[7]);
-                if (h < 0)
-                        return -EINVAL;
-
-                *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
-                *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
-                *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
-                *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
-                *(z++) = (uint8_t) g << 5 | (uint8_t) h;                         /* VVVRRRRR */
-        }
-
-        switch (l % 8) {
-        case 7:
-                a = unbase32hexchar(x[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unbase32hexchar(x[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                c = unbase32hexchar(x[2]);
-                if (c < 0)
-                        return -EINVAL;
-
-                d = unbase32hexchar(x[3]);
-                if (d < 0)
-                        return -EINVAL;
-
-                e = unbase32hexchar(x[4]);
-                if (e < 0)
-                        return -EINVAL;
-
-                f = unbase32hexchar(x[5]);
-                if (f < 0)
-                        return -EINVAL;
-
-                g = unbase32hexchar(x[6]);
-                if (g < 0)
-                        return -EINVAL;
-
-                /* g == 000VV000 */
-                if (g & 7)
-                        return -EINVAL;
-
-                *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
-                *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
-                *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
-                *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
-
-                break;
-        case 5:
-                a = unbase32hexchar(x[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unbase32hexchar(x[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                c = unbase32hexchar(x[2]);
-                if (c < 0)
-                        return -EINVAL;
-
-                d = unbase32hexchar(x[3]);
-                if (d < 0)
-                        return -EINVAL;
-
-                e = unbase32hexchar(x[4]);
-                if (e < 0)
-                        return -EINVAL;
-
-                /* e == 000SSSS0 */
-                if (e & 1)
-                        return -EINVAL;
-
-                *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
-                *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
-                *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
-
-                break;
-        case 4:
-                a = unbase32hexchar(x[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unbase32hexchar(x[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                c = unbase32hexchar(x[2]);
-                if (c < 0)
-                        return -EINVAL;
-
-                d = unbase32hexchar(x[3]);
-                if (d < 0)
-                        return -EINVAL;
-
-                /* d == 000W0000 */
-                if (d & 15)
-                        return -EINVAL;
-
-                *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
-                *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
-
-                break;
-        case 2:
-                a = unbase32hexchar(x[0]);
-                if (a < 0)
-                        return -EINVAL;
-
-                b = unbase32hexchar(x[1]);
-                if (b < 0)
-                        return -EINVAL;
-
-                /* b == 000YYY00 */
-                if (b & 3)
-                        return -EINVAL;
-
-                *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
-
-                break;
-        case 0:
-                break;
-        default:
-                return -EINVAL;
-        }
-
-        *z = 0;
-
-        *mem = TAKE_PTR(r);
-        *_len = len;
-
-        return 0;
-}
-
-/* https://tools.ietf.org/html/rfc4648#section-4 */
-char base64char(int x) {
-        static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                      "abcdefghijklmnopqrstuvwxyz"
-                                      "0123456789+/";
-        return table[x & 63];
-}
-
-int unbase64char(char c) {
-        unsigned offset;
-
-        if (c >= 'A' && c <= 'Z')
-                return c - 'A';
-
-        offset = 'Z' - 'A' + 1;
-
-        if (c >= 'a' && c <= 'z')
-                return c - 'a' + offset;
-
-        offset += 'z' - 'a' + 1;
-
-        if (c >= '0' && c <= '9')
-                return c - '0' + offset;
-
-        offset += '9' - '0' + 1;
-
-        if (c == '+')
-                return offset;
-
-        offset++;
-
-        if (c == '/')
-                return offset;
-
-        return -EINVAL;
-}
-
-ssize_t base64mem(const void *p, size_t l, char **out) {
-        char *r, *z;
-        const uint8_t *x;
-
-        assert(p || l == 0);
-        assert(out);
-
-        /* three input bytes makes four output bytes, padding is added so we must round up */
-        z = r = malloc(4 * (l + 2) / 3 + 1);
-        if (!r)
-                return -ENOMEM;
-
-        for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
-                /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
-                *(z++) = base64char(x[0] >> 2);                    /* 00XXXXXX */
-                *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4);  /* 00XXYYYY */
-                *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
-                *(z++) = base64char(x[2] & 63);                    /* 00ZZZZZZ */
-        }
-
-        switch (l % 3) {
-        case 2:
-                *(z++) = base64char(x[0] >> 2);                   /* 00XXXXXX */
-                *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
-                *(z++) = base64char((x[1] & 15) << 2);            /* 00YYYY00 */
-                *(z++) = '=';
-
-                break;
-        case 1:
-                *(z++) = base64char(x[0] >> 2);        /* 00XXXXXX */
-                *(z++) = base64char((x[0] & 3) << 4);  /* 00XX0000 */
-                *(z++) = '=';
-                *(z++) = '=';
-
-                break;
-        }
-
-        *z = 0;
-        *out = r;
-        return z - r;
-}
-
-static int base64_append_width(
-                char **prefix, int plen,
-                const char *sep, int indent,
-                const void *p, size_t l,
-                int width) {
-
-        _cleanup_free_ char *x = NULL;
-        char *t, *s;
-        ssize_t slen, len, avail;
-        int line, lines;
-
-        len = base64mem(p, l, &x);
-        if (len <= 0)
-                return len;
-
-        lines = DIV_ROUND_UP(len, width);
-
-        slen = strlen_ptr(sep);
-        t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines);
-        if (!t)
-                return -ENOMEM;
-
-        memcpy_safe(t + plen, sep, slen);
-
-        for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
-                int act = MIN(width, avail);
-
-                if (line > 0 || sep) {
-                        memset(s, ' ', indent);
-                        s += indent;
-                }
-
-                memcpy(s, x + width * line, act);
-                s += act;
-                *(s++) = line < lines - 1 ? '\n' : '\0';
-                avail -= act;
-        }
-        assert(avail == 0);
-
-        *prefix = t;
-        return 0;
-}
-
-int base64_append(
-                char **prefix, int plen,
-                const void *p, size_t l,
-                int indent, int width) {
-
-        if (plen > width / 2 || plen + indent > width)
-                /* leave indent on the left, keep last column free */
-                return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1);
-        else
-                /* leave plen on the left, keep last column free */
-                return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1);
-}
-
-static int unbase64_next(const char **p, size_t *l) {
-        int ret;
-
-        assert(p);
-        assert(l);
-
-        /* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
-         * greedily skip all preceeding and all following whitespace. */
-
-        for (;;) {
-                if (*l == 0)
-                        return -EPIPE;
-
-                if (!strchr(WHITESPACE, **p))
-                        break;
-
-                /* Skip leading whitespace */
-                (*p)++, (*l)--;
-        }
-
-        if (**p == '=')
-                ret = INT_MAX; /* return padding as INT_MAX */
-        else {
-                ret = unbase64char(**p);
-                if (ret < 0)
-                        return ret;
-        }
-
-        for (;;) {
-                (*p)++, (*l)--;
-
-                if (*l == 0)
-                        break;
-                if (!strchr(WHITESPACE, **p))
-                        break;
-
-                /* Skip following whitespace */
-        }
-
-        return ret;
-}
-
-int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
-        _cleanup_free_ uint8_t *buf = NULL;
-        const char *x;
-        uint8_t *z;
-        size_t len;
-
-        assert(p || l == 0);
-        assert(ret);
-        assert(ret_size);
-
-        if (l == (size_t) -1)
-                l = strlen(p);
-
-        /* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
-         * bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
-        len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
-
-        buf = malloc(len + 1);
-        if (!buf)
-                return -ENOMEM;
-
-        for (x = p, z = buf;;) {
-                int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
-
-                a = unbase64_next(&x, &l);
-                if (a == -EPIPE) /* End of string */
-                        break;
-                if (a < 0)
-                        return a;
-                if (a == INT_MAX) /* Padding is not allowed at the beginning of a 4ch block */
-                        return -EINVAL;
-
-                b = unbase64_next(&x, &l);
-                if (b < 0)
-                        return b;
-                if (b == INT_MAX) /* Padding is not allowed at the second character of a 4ch block either */
-                        return -EINVAL;
-
-                c = unbase64_next(&x, &l);
-                if (c < 0)
-                        return c;
-
-                d = unbase64_next(&x, &l);
-                if (d < 0)
-                        return d;
-
-                if (c == INT_MAX) { /* Padding at the third character */
-
-                        if (d != INT_MAX) /* If the third character is padding, the fourth must be too */
-                                return -EINVAL;
-
-                        /* b == 00YY0000 */
-                        if (b & 15)
-                                return -EINVAL;
-
-                        if (l > 0) /* Trailing rubbish? */
-                                return -ENAMETOOLONG;
-
-                        *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
-                        break;
-                }
-
-                if (d == INT_MAX) {
-                        /* c == 00ZZZZ00 */
-                        if (c & 3)
-                                return -EINVAL;
-
-                        if (l > 0) /* Trailing rubbish? */
-                                return -ENAMETOOLONG;
-
-                        *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
-                        *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
-                        break;
-                }
-
-                *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
-                *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
-                *(z++) = (uint8_t) c << 6 | (uint8_t) d;      /* ZZWWWWWW */
-        }
-
-        *z = 0;
-
-        *ret_size = (size_t) (z - buf);
-        *ret = TAKE_PTR(buf);
-
-        return 0;
-}
-
-void hexdump(FILE *f, const void *p, size_t s) {
-        const uint8_t *b = p;
-        unsigned n = 0;
-
-        assert(b || s == 0);
-
-        if (!f)
-                f = stdout;
-
-        while (s > 0) {
-                size_t i;
-
-                fprintf(f, "%04x  ", n);
-
-                for (i = 0; i < 16; i++) {
-
-                        if (i >= s)
-                                fputs("   ", f);
-                        else
-                                fprintf(f, "%02x ", b[i]);
-
-                        if (i == 7)
-                                fputc(' ', f);
-                }
-
-                fputc(' ', f);
-
-                for (i = 0; i < 16; i++) {
-
-                        if (i >= s)
-                                fputc(' ', f);
-                        else
-                                fputc(isprint(b[i]) ? (char) b[i] : '.', f);
-                }
-
-                fputc('\n', f);
-
-                if (s < 16)
-                        break;
-
-                n += 16;
-                b += 16;
-                s -= 16;
-        }
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/hexdecoct.h b/src/systemd/src/basic/hexdecoct.h
deleted file mode 100644
index 9477d16e..00000000
--- a/src/systemd/src/basic/hexdecoct.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "macro.h"
-
-char octchar(int x) _const_;
-int unoctchar(char c) _const_;
-
-char decchar(int x) _const_;
-int undecchar(char c) _const_;
-
-char hexchar(int x) _const_;
-int unhexchar(char c) _const_;
-
-char *hexmem(const void *p, size_t l);
-int unhexmem(const char *p, size_t l, void **mem, size_t *len);
-
-char base32hexchar(int x) _const_;
-int unbase32hexchar(char c) _const_;
-
-char base64char(int x) _const_;
-int unbase64char(char c) _const_;
-
-char *base32hexmem(const void *p, size_t l, bool padding);
-int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len);
-
-ssize_t base64mem(const void *p, size_t l, char **out);
-int base64_append(char **prefix, int plen,
-                  const void *p, size_t l,
-                  int margin, int width);
-int unbase64mem(const char *p, size_t l, void **mem, size_t *len);
-
-void hexdump(FILE *f, const void *p, size_t s);
diff --git a/src/systemd/src/basic/hostname-util.c b/src/systemd/src/basic/hostname-util.c
deleted file mode 100644
index 85708394..00000000
--- a/src/systemd/src/basic/hostname-util.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/utsname.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "def.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "hostname-util.h"
-#include "macro.h"
-#include "string-util.h"
-
-#if 0 /* NM_IGNORED */
-bool hostname_is_set(void) {
-        struct utsname u;
-
-        assert_se(uname(&u) >= 0);
-
-        if (isempty(u.nodename))
-                return false;
-
-        /* This is the built-in kernel default host name */
-        if (streq(u.nodename, "(none)"))
-                return false;
-
-        return true;
-}
-
-char* gethostname_malloc(void) {
-        struct utsname u;
-
-        /* This call tries to return something useful, either the actual hostname
-         * or it makes something up. The only reason it might fail is OOM.
-         * It might even return "localhost" if that's set. */
-
-        assert_se(uname(&u) >= 0);
-
-        if (isempty(u.nodename) || streq(u.nodename, "(none)"))
-                return strdup(FALLBACK_HOSTNAME);
-
-        return strdup(u.nodename);
-}
-#endif /* NM_IGNORED */
-
-int gethostname_strict(char **ret) {
-        struct utsname u;
-        char *k;
-
-        /* This call will rather fail than make up a name. It will not return "localhost" either. */
-
-        assert_se(uname(&u) >= 0);
-
-        if (isempty(u.nodename))
-                return -ENXIO;
-
-        if (streq(u.nodename, "(none)"))
-                return -ENXIO;
-
-        if (is_localhost(u.nodename))
-                return -ENXIO;
-
-        k = strdup(u.nodename);
-        if (!k)
-                return -ENOMEM;
-
-        *ret = k;
-        return 0;
-}
-
-static bool hostname_valid_char(char c) {
-        return
-                (c >= 'a' && c <= 'z') ||
-                (c >= 'A' && c <= 'Z') ||
-                (c >= '0' && c <= '9') ||
-                IN_SET(c, '-', '_', '.');
-}
-
-/**
- * Check if s looks like a valid host name or FQDN. This does not do
- * full DNS validation, but only checks if the name is composed of
- * allowed characters and the length is not above the maximum allowed
- * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
- * allow_trailing_dot is true and at least two components are present
- * in the name. Note that due to the restricted charset and length
- * this call is substantially more conservative than
- * dns_name_is_valid().
- */
-bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
-        unsigned n_dots = 0;
-        const char *p;
-        bool dot;
-
-        if (isempty(s))
-                return false;
-
-        /* Doesn't accept empty hostnames, hostnames with
-         * leading dots, and hostnames with multiple dots in a
-         * sequence. Also ensures that the length stays below
-         * HOST_NAME_MAX. */
-
-        for (p = s, dot = true; *p; p++) {
-                if (*p == '.') {
-                        if (dot)
-                                return false;
-
-                        dot = true;
-                        n_dots++;
-                } else {
-                        if (!hostname_valid_char(*p))
-                                return false;
-
-                        dot = false;
-                }
-        }
-
-        if (dot && (n_dots < 2 || !allow_trailing_dot))
-                return false;
-
-        if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
-                                  * Linux, but DNS allows domain names
-                                  * up to 255 characters */
-                return false;
-
-        return true;
-}
-
-char* hostname_cleanup(char *s) {
-        char *p, *d;
-        bool dot;
-
-        assert(s);
-
-        strshorten(s, HOST_NAME_MAX);
-
-        for (p = s, d = s, dot = true; *p; p++) {
-                if (*p == '.') {
-                        if (dot)
-                                continue;
-
-                        *(d++) = '.';
-                        dot = true;
-                } else if (hostname_valid_char(*p)) {
-                        *(d++) = *p;
-                        dot = false;
-                }
-        }
-
-        if (dot && d > s)
-                d[-1] = 0;
-        else
-                *d = 0;
-
-        return s;
-}
-
-bool is_localhost(const char *hostname) {
-        assert(hostname);
-
-        /* This tries to identify local host and domain names
-         * described in RFC6761 plus the redhatism of localdomain */
-
-        return strcaseeq(hostname, "localhost") ||
-               strcaseeq(hostname, "localhost.") ||
-               strcaseeq(hostname, "localhost.localdomain") ||
-               strcaseeq(hostname, "localhost.localdomain.") ||
-               endswith_no_case(hostname, ".localhost") ||
-               endswith_no_case(hostname, ".localhost.") ||
-               endswith_no_case(hostname, ".localhost.localdomain") ||
-               endswith_no_case(hostname, ".localhost.localdomain.");
-}
-
-#if 0 /* NM_IGNORED */
-bool is_gateway_hostname(const char *hostname) {
-        assert(hostname);
-
-        /* This tries to identify the valid syntaxes for the our
-         * synthetic "gateway" host. */
-
-        return
-                strcaseeq(hostname, "_gateway") || strcaseeq(hostname, "_gateway.")
-#if ENABLE_COMPAT_GATEWAY_HOSTNAME
-                || strcaseeq(hostname, "gateway") || strcaseeq(hostname, "gateway.")
-#endif
-                ;
-}
-
-int sethostname_idempotent(const char *s) {
-        char buf[HOST_NAME_MAX + 1] = {};
-
-        assert(s);
-
-        if (gethostname(buf, sizeof(buf)) < 0)
-                return -errno;
-
-        if (streq(buf, s))
-                return 0;
-
-        if (sethostname(s, strlen(s)) < 0)
-                return -errno;
-
-        return 1;
-}
-
-int shorten_overlong(const char *s, char **ret) {
-        char *h, *p;
-
-        /* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
-         * whatever comes earlier. */
-
-        assert(s);
-
-        h = strdup(s);
-        if (!h)
-                return -ENOMEM;
-
-        if (hostname_is_valid(h, false)) {
-                *ret = h;
-                return 0;
-        }
-
-        p = strchr(h, '.');
-        if (p)
-                *p = 0;
-
-        strshorten(h, HOST_NAME_MAX);
-
-        if (!hostname_is_valid(h, false)) {
-                free(h);
-                return -EDOM;
-        }
-
-        *ret = h;
-        return 1;
-}
-
-int read_etc_hostname_stream(FILE *f, char **ret) {
-        int r;
-
-        assert(f);
-        assert(ret);
-
-        for (;;) {
-                _cleanup_free_ char *line = NULL;
-                char *p;
-
-                r = read_line(f, LONG_LINE_MAX, &line);
-                if (r < 0)
-                        return r;
-                if (r == 0) /* EOF without any hostname? the file is empty, let's treat that exactly like no file at all: ENOENT */
-                        return -ENOENT;
-
-                p = strstrip(line);
-
-                /* File may have empty lines or comments, ignore them */
-                if (!IN_SET(*p, '\0', '#')) {
-                        char *copy;
-
-                        hostname_cleanup(p); /* normalize the hostname */
-
-                        if (!hostname_is_valid(p, true)) /* check that the hostname we return is valid */
-                                return -EBADMSG;
-
-                        copy = strdup(p);
-                        if (!copy)
-                                return -ENOMEM;
-
-                        *ret = copy;
-                        return 0;
-                }
-        }
-}
-
-int read_etc_hostname(const char *path, char **ret) {
-        _cleanup_fclose_ FILE *f = NULL;
-
-        assert(ret);
-
-        if (!path)
-                path = "/etc/hostname";
-
-        f = fopen(path, "re");
-        if (!f)
-                return -errno;
-
-        return read_etc_hostname_stream(f, ret);
-
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/hostname-util.h b/src/systemd/src/basic/hostname-util.h
deleted file mode 100644
index 74948172..00000000
--- a/src/systemd/src/basic/hostname-util.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stdio.h>
-
-#include "macro.h"
-
-bool hostname_is_set(void);
-
-char* gethostname_malloc(void);
-int gethostname_strict(char **ret);
-
-bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_;
-char* hostname_cleanup(char *s);
-
-#define machine_name_is_valid(s) hostname_is_valid(s, false)
-
-bool is_localhost(const char *hostname);
-bool is_gateway_hostname(const char *hostname);
-
-int sethostname_idempotent(const char *s);
-
-int shorten_overlong(const char *s, char **ret);
-
-int read_etc_hostname_stream(FILE *f, char **ret);
-int read_etc_hostname(const char *path, char **ret);
diff --git a/src/systemd/src/basic/in-addr-util.c b/src/systemd/src/basic/in-addr-util.c
deleted file mode 100644
index 19d0db25..00000000
--- a/src/systemd/src/basic/in-addr-util.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <arpa/inet.h>
-#include <endian.h>
-#include <errno.h>
-#include <net/if.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "alloc-util.h"
-#include "in-addr-util.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "util.h"
-
-bool in4_addr_is_null(const struct in_addr *a) {
-        assert(a);
-
-        return a->s_addr == 0;
-}
-
-int in_addr_is_null(int family, const union in_addr_union *u) {
-        assert(u);
-
-        if (family == AF_INET)
-                return in4_addr_is_null(&u->in);
-
-        if (family == AF_INET6)
-                return IN6_IS_ADDR_UNSPECIFIED(&u->in6);
-
-        return -EAFNOSUPPORT;
-}
-
-bool in4_addr_is_link_local(const struct in_addr *a) {
-        assert(a);
-
-        return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
-}
-
-int in_addr_is_link_local(int family, const union in_addr_union *u) {
-        assert(u);
-
-        if (family == AF_INET)
-                return in4_addr_is_link_local(&u->in);
-
-        if (family == AF_INET6)
-                return IN6_IS_ADDR_LINKLOCAL(&u->in6);
-
-        return -EAFNOSUPPORT;
-}
-
-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));
-
-        if (family == AF_INET6)
-                return IN6_IS_ADDR_MULTICAST(&u->in6);
-
-        return -EAFNOSUPPORT;
-}
-
-bool in4_addr_is_localhost(const struct in_addr *a) {
-        assert(a);
-
-        /* All of 127.x.x.x is localhost. */
-        return (be32toh(a->s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
-}
-
-int in_addr_is_localhost(int family, const union in_addr_union *u) {
-        assert(u);
-
-        if (family == AF_INET)
-                return in4_addr_is_localhost(&u->in);
-
-        if (family == AF_INET6)
-                return IN6_IS_ADDR_LOOPBACK(&u->in6);
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) {
-        assert(a);
-        assert(b);
-
-        if (family == AF_INET)
-                return a->in.s_addr == b->in.s_addr;
-
-        if (family == AF_INET6)
-                return
-                        a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
-                        a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
-                        a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
-                        a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_intersect(
-                int family,
-                const union in_addr_union *a,
-                unsigned aprefixlen,
-                const union in_addr_union *b,
-                unsigned bprefixlen) {
-
-        unsigned m;
-
-        assert(a);
-        assert(b);
-
-        /* Checks whether there are any addresses that are in both
-         * networks */
-
-        m = MIN(aprefixlen, bprefixlen);
-
-        if (family == AF_INET) {
-                uint32_t x, nm;
-
-                x = be32toh(a->in.s_addr ^ b->in.s_addr);
-                nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
-
-                return (x & nm) == 0;
-        }
-
-        if (family == AF_INET6) {
-                unsigned i;
-
-                if (m > 128)
-                        m = 128;
-
-                for (i = 0; i < 16; i++) {
-                        uint8_t x, nm;
-
-                        x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
-
-                        if (m < 8)
-                                nm = 0xFF << (8 - m);
-                        else
-                                nm = 0xFF;
-
-                        if ((x & nm) != 0)
-                                return 0;
-
-                        if (m > 8)
-                                m -= 8;
-                        else
-                                m = 0;
-                }
-
-                return 1;
-        }
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) {
-        assert(u);
-
-        /* Increases the network part of an address by one. Returns
-         * positive it that succeeds, or 0 if this overflows. */
-
-        if (prefixlen <= 0)
-                return 0;
-
-        if (family == AF_INET) {
-                uint32_t c, n;
-
-                if (prefixlen > 32)
-                        prefixlen = 32;
-
-                c = be32toh(u->in.s_addr);
-                n = c + (1UL << (32 - prefixlen));
-                if (n < c)
-                        return 0;
-                n &= 0xFFFFFFFFUL << (32 - prefixlen);
-
-                u->in.s_addr = htobe32(n);
-                return 1;
-        }
-
-        if (family == AF_INET6) {
-                struct in6_addr add = {}, result;
-                uint8_t overflow = 0;
-                unsigned i;
-
-                if (prefixlen > 128)
-                        prefixlen = 128;
-
-                /* First calculate what we have to add */
-                add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
-
-                for (i = 16; i > 0; i--) {
-                        unsigned j = i - 1;
-
-                        result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
-                        overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
-                }
-
-                if (overflow)
-                        return 0;
-
-                u->in6 = result;
-                return 1;
-        }
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
-        char *x;
-        size_t l;
-
-        assert(u);
-        assert(ret);
-
-        if (family == AF_INET)
-                l = INET_ADDRSTRLEN;
-        else if (family == AF_INET6)
-                l = INET6_ADDRSTRLEN;
-        else
-                return -EAFNOSUPPORT;
-
-        x = new(char, l);
-        if (!x)
-                return -ENOMEM;
-
-        errno = 0;
-        if (!inet_ntop(family, u, x, l)) {
-                free(x);
-                return errno > 0 ? -errno : -EINVAL;
-        }
-
-        *ret = x;
-        return 0;
-}
-
-int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) {
-        size_t l;
-        char *x;
-        int r;
-
-        assert(u);
-        assert(ret);
-
-        /* Much like in_addr_to_string(), but optionally appends the zone interface index to the address, to properly
-         * handle IPv6 link-local addresses. */
-
-        if (family != AF_INET6)
-                goto fallback;
-        if (ifindex <= 0)
-                goto fallback;
-
-        r = in_addr_is_link_local(family, u);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                goto fallback;
-
-        l = INET6_ADDRSTRLEN + 1 + DECIMAL_STR_MAX(ifindex) + 1;
-        x = new(char, l);
-        if (!x)
-                return -ENOMEM;
-
-        errno = 0;
-        if (!inet_ntop(family, u, x, l)) {
-                free(x);
-                return errno > 0 ? -errno : -EINVAL;
-        }
-
-        sprintf(strchr(x, 0), "%%%i", ifindex);
-        *ret = x;
-
-        return 0;
-
-fallback:
-        return in_addr_to_string(family, u, ret);
-}
-
-int in_addr_from_string(int family, const char *s, union in_addr_union *ret) {
-        union in_addr_union buffer;
-        assert(s);
-
-        if (!IN_SET(family, AF_INET, AF_INET6))
-                return -EAFNOSUPPORT;
-
-        errno = 0;
-        if (inet_pton(family, s, ret ?: &buffer) <= 0)
-                return errno > 0 ? -errno : -EINVAL;
-
-        return 0;
-}
-
-int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret) {
-        int r;
-
-        assert(s);
-
-        r = in_addr_from_string(AF_INET, s, ret);
-        if (r >= 0) {
-                if (ret_family)
-                        *ret_family = AF_INET;
-                return 0;
-        }
-
-        r = in_addr_from_string(AF_INET6, s, ret);
-        if (r >= 0) {
-                if (ret_family)
-                        *ret_family = AF_INET6;
-                return 0;
-        }
-
-        return -EINVAL;
-}
-
-#if 0 /* NM_IGNORED */
-int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex) {
-        const char *suffix;
-        int r, ifi = 0;
-
-        assert(s);
-        assert(family);
-        assert(ret);
-
-        /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id")
-         * if one is found. */
-
-        suffix = strchr(s, '%');
-        if (suffix) {
-
-                if (ifindex) {
-                        /* If we shall return the interface index, try to parse it */
-                        r = parse_ifindex(suffix + 1, &ifi);
-                        if (r < 0) {
-                                unsigned u;
-
-                                u = if_nametoindex(suffix + 1);
-                                if (u <= 0)
-                                        return -errno;
-
-                                ifi = (int) u;
-                        }
-                }
-
-                s = strndupa(s, suffix - s);
-        }
-
-        r = in_addr_from_string_auto(s, family, ret);
-        if (r < 0)
-                return r;
-
-        if (ifindex)
-                *ifindex = ifi;
-
-        return r;
-}
-#endif /* NM_IGNORED */
-
-unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) {
-        assert(addr);
-
-        return 32 - u32ctz(be32toh(addr->s_addr));
-}
-
-struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen) {
-        assert(addr);
-        assert(prefixlen <= 32);
-
-        /* Shifting beyond 32 is not defined, handle this specially. */
-        if (prefixlen == 0)
-                addr->s_addr = 0;
-        else
-                addr->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff);
-
-        return addr;
-}
-
-int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) {
-        uint8_t msb_octet = *(uint8_t*) addr;
-
-        /* addr may not be aligned, so make sure we only access it byte-wise */
-
-        assert(addr);
-        assert(prefixlen);
-
-        if (msb_octet < 128)
-                /* class A, leading bits: 0 */
-                *prefixlen = 8;
-        else if (msb_octet < 192)
-                /* class B, leading bits 10 */
-                *prefixlen = 16;
-        else if (msb_octet < 224)
-                /* class C, leading bits 110 */
-                *prefixlen = 24;
-        else
-                /* class D or E, no default prefixlen */
-                return -ERANGE;
-
-        return 0;
-}
-
-int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) {
-        unsigned char prefixlen;
-        int r;
-
-        assert(addr);
-        assert(mask);
-
-        r = in4_addr_default_prefixlen(addr, &prefixlen);
-        if (r < 0)
-                return r;
-
-        in4_addr_prefixlen_to_netmask(mask, prefixlen);
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen) {
-        assert(addr);
-
-        if (family == AF_INET) {
-                struct in_addr mask;
-
-                if (!in4_addr_prefixlen_to_netmask(&mask, prefixlen))
-                        return -EINVAL;
-
-                addr->in.s_addr &= mask.s_addr;
-                return 0;
-        }
-
-        if (family == AF_INET6) {
-                unsigned i;
-
-                for (i = 0; i < 16; i++) {
-                        uint8_t mask;
-
-                        if (prefixlen >= 8) {
-                                mask = 0xFF;
-                                prefixlen -= 8;
-                        } else {
-                                mask = 0xFF << (8 - prefixlen);
-                                prefixlen = 0;
-                        }
-
-                        addr->in6.s6_addr[i] &= mask;
-                }
-
-                return 0;
-        }
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_covers(int family,
-                          const union in_addr_union *prefix,
-                          unsigned char prefixlen,
-                          const union in_addr_union *address) {
-
-        union in_addr_union masked_prefix, masked_address;
-        int r;
-
-        assert(prefix);
-        assert(address);
-
-        masked_prefix = *prefix;
-        r = in_addr_mask(family, &masked_prefix, prefixlen);
-        if (r < 0)
-                return r;
-
-        masked_address = *address;
-        r = in_addr_mask(family, &masked_address, prefixlen);
-        if (r < 0)
-                return r;
-
-        return in_addr_equal(family, &masked_prefix, &masked_address);
-}
-
-int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret) {
-        uint8_t u;
-        int r;
-
-        if (!IN_SET(family, AF_INET, AF_INET6))
-                return -EAFNOSUPPORT;
-
-        r = safe_atou8(p, &u);
-        if (r < 0)
-                return r;
-
-        if (u > FAMILY_ADDRESS_SIZE(family) * 8)
-                return -ERANGE;
-
-        *ret = u;
-        return 0;
-}
-
-int in_addr_prefix_from_string(
-                const char *p,
-                int family,
-                union in_addr_union *ret_prefix,
-                unsigned char *ret_prefixlen) {
-
-        union in_addr_union buffer;
-        const char *e, *l;
-        unsigned char k;
-        int r;
-
-        assert(p);
-
-        if (!IN_SET(family, AF_INET, AF_INET6))
-                return -EAFNOSUPPORT;
-
-        e = strchr(p, '/');
-        if (e)
-                l = strndupa(p, e - p);
-        else
-                l = p;
-
-        r = in_addr_from_string(family, l, &buffer);
-        if (r < 0)
-                return r;
-
-        if (e) {
-                r = in_addr_parse_prefixlen(family, e+1, &k);
-                if (r < 0)
-                        return r;
-        } else
-                k = FAMILY_ADDRESS_SIZE(family) * 8;
-
-        if (ret_prefix)
-                *ret_prefix = buffer;
-        if (ret_prefixlen)
-                *ret_prefixlen = k;
-
-        return 0;
-}
-
-int in_addr_prefix_from_string_auto(
-                const char *p,
-                int *ret_family,
-                union in_addr_union *ret_prefix,
-                unsigned char *ret_prefixlen) {
-
-        union in_addr_union buffer;
-        const char *e, *l;
-        unsigned char k;
-        int family, r;
-
-        assert(p);
-
-        e = strchr(p, '/');
-        if (e)
-                l = strndupa(p, e - p);
-        else
-                l = p;
-
-        r = in_addr_from_string_auto(l, &family, &buffer);
-        if (r < 0)
-                return r;
-
-        if (e) {
-                r = in_addr_parse_prefixlen(family, e+1, &k);
-                if (r < 0)
-                        return r;
-        } else
-                k = FAMILY_ADDRESS_SIZE(family) * 8;
-
-        if (ret_family)
-                *ret_family = family;
-        if (ret_prefix)
-                *ret_prefix = buffer;
-        if (ret_prefixlen)
-                *ret_prefixlen = k;
-
-        return 0;
-
-}
-
-void in_addr_data_hash_func(const void *p, struct siphash *state) {
-        const struct in_addr_data *a = p;
-
-        siphash24_compress(&a->family, sizeof(a->family), state);
-        siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
-}
-
-int in_addr_data_compare_func(const void *a, const void *b) {
-        const struct in_addr_data *x = a, *y = b;
-        int r;
-
-        r = CMP(x->family, y->family);
-        if (r != 0)
-                return r;
-
-        return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
-}
-
-const struct hash_ops in_addr_data_hash_ops = {
-        .hash = in_addr_data_hash_func,
-        .compare = in_addr_data_compare_func,
-};
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/in-addr-util.h b/src/systemd/src/basic/in-addr-util.h
deleted file mode 100644
index e4be30dc..00000000
--- a/src/systemd/src/basic/in-addr-util.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <netinet/in.h>
-#include <stddef.h>
-#include <sys/socket.h>
-
-#include "hash-funcs.h"
-#include "macro.h"
-#include "util.h"
-
-union in_addr_union {
-        struct in_addr in;
-        struct in6_addr in6;
-};
-
-struct in_addr_data {
-        int family;
-        union in_addr_union address;
-};
-
-bool in4_addr_is_null(const struct in_addr *a);
-int in_addr_is_null(int family, const union in_addr_union *u);
-
-int in_addr_is_multicast(int family, const union in_addr_union *u);
-
-bool in4_addr_is_link_local(const struct in_addr *a);
-int in_addr_is_link_local(int family, const union in_addr_union *u);
-
-bool in4_addr_is_localhost(const struct in_addr *a);
-int in_addr_is_localhost(int family, const union in_addr_union *u);
-
-int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
-int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
-int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
-int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
-int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret);
-int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
-int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret);
-int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex);
-unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr);
-struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen);
-int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
-int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask);
-int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen);
-int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address);
-int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret);
-int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
-int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
-
-static inline size_t FAMILY_ADDRESS_SIZE(int family) {
-        assert(IN_SET(family, AF_INET, AF_INET6));
-        return family == AF_INET6 ? 16 : 4;
-}
-
-#define IN_ADDR_NULL ((union in_addr_union) {})
-
-void in_addr_data_hash_func(const void *p, struct siphash *state);
-int in_addr_data_compare_func(const void *a, const void *b);
-extern const struct hash_ops in_addr_data_hash_ops;
diff --git a/src/systemd/src/basic/io-util.c b/src/systemd/src/basic/io-util.c
deleted file mode 100644
index 6f46c944..00000000
--- a/src/systemd/src/basic/io-util.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <poll.h>
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "io-util.h"
-#include "time-util.h"
-
-int flush_fd(int fd) {
-        struct pollfd pollfd = {
-                .fd = fd,
-                .events = POLLIN,
-        };
-        int count = 0;
-
-        /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
-         * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
-         * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
-         * was set to non-blocking too. */
-
-        for (;;) {
-                char buf[LINE_MAX];
-                ssize_t l;
-                int r;
-
-                r = poll(&pollfd, 1, 0);
-                if (r < 0) {
-                        if (errno == EINTR)
-                                continue;
-
-                        return -errno;
-
-                } else if (r == 0)
-                        return count;
-
-                l = read(fd, buf, sizeof(buf));
-                if (l < 0) {
-
-                        if (errno == EINTR)
-                                continue;
-
-                        if (errno == EAGAIN)
-                                return count;
-
-                        return -errno;
-                } else if (l == 0)
-                        return count;
-
-                count += (int) l;
-        }
-}
-
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
-        uint8_t *p = buf;
-        ssize_t n = 0;
-
-        assert(fd >= 0);
-        assert(buf);
-
-        /* If called with nbytes == 0, let's call read() at least
-         * once, to validate the operation */
-
-        if (nbytes > (size_t) SSIZE_MAX)
-                return -EINVAL;
-
-        do {
-                ssize_t k;
-
-                k = read(fd, p, nbytes);
-                if (k < 0) {
-                        if (errno == EINTR)
-                                continue;
-
-                        if (errno == EAGAIN && do_poll) {
-
-                                /* We knowingly ignore any return value here,
-                                 * and expect that any error/EOF is reported
-                                 * via read() */
-
-                                (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
-                                continue;
-                        }
-
-                        return n > 0 ? n : -errno;
-                }
-
-                if (k == 0)
-                        return n;
-
-                assert((size_t) k <= nbytes);
-
-                p += k;
-                nbytes -= k;
-                n += k;
-        } while (nbytes > 0);
-
-        return n;
-}
-
-int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
-        ssize_t n;
-
-        n = loop_read(fd, buf, nbytes, do_poll);
-        if (n < 0)
-                return (int) n;
-        if ((size_t) n != nbytes)
-                return -EIO;
-
-        return 0;
-}
-
-int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
-        const uint8_t *p = buf;
-
-        assert(fd >= 0);
-        assert(buf);
-
-        if (_unlikely_(nbytes > (size_t) SSIZE_MAX))
-                return -EINVAL;
-
-        do {
-                ssize_t k;
-
-                k = write(fd, p, nbytes);
-                if (k < 0) {
-                        if (errno == EINTR)
-                                continue;
-
-                        if (errno == EAGAIN && do_poll) {
-                                /* We knowingly ignore any return value here,
-                                 * and expect that any error/EOF is reported
-                                 * via write() */
-
-                                (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
-                                continue;
-                        }
-
-                        return -errno;
-                }
-
-                if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
-                        return -EIO;
-
-                assert((size_t) k <= nbytes);
-
-                p += k;
-                nbytes -= k;
-        } while (nbytes > 0);
-
-        return 0;
-}
-
-int pipe_eof(int fd) {
-        struct pollfd pollfd = {
-                .fd = fd,
-                .events = POLLIN|POLLHUP,
-        };
-
-        int r;
-
-        r = poll(&pollfd, 1, 0);
-        if (r < 0)
-                return -errno;
-
-        if (r == 0)
-                return 0;
-
-        return pollfd.revents & POLLHUP;
-}
-
-int fd_wait_for_event(int fd, int event, usec_t t) {
-
-        struct pollfd pollfd = {
-                .fd = fd,
-                .events = event,
-        };
-
-        struct timespec ts;
-        int r;
-
-        r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
-        if (r < 0)
-                return -errno;
-        if (r == 0)
-                return 0;
-
-        return pollfd.revents;
-}
-
-static size_t nul_length(const uint8_t *p, size_t sz) {
-        size_t n = 0;
-
-        while (sz > 0) {
-                if (*p != 0)
-                        break;
-
-                n++;
-                p++;
-                sz--;
-        }
-
-        return n;
-}
-
-ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
-        const uint8_t *q, *w, *e;
-        ssize_t l;
-
-        q = w = p;
-        e = q + sz;
-        while (q < e) {
-                size_t n;
-
-                n = nul_length(q, e - q);
-
-                /* If there are more than the specified run length of
-                 * NUL bytes, or if this is the beginning or the end
-                 * of the buffer, then seek instead of write */
-                if ((n > run_length) ||
-                    (n > 0 && q == p) ||
-                    (n > 0 && q + n >= e)) {
-                        if (q > w) {
-                                l = write(fd, w, q - w);
-                                if (l < 0)
-                                        return -errno;
-                                if (l != q -w)
-                                        return -EIO;
-                        }
-
-                        if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
-                                return -errno;
-
-                        q += n;
-                        w = q;
-                } else if (n > 0)
-                        q += n;
-                else
-                        q++;
-        }
-
-        if (q > w) {
-                l = write(fd, w, q - w);
-                if (l < 0)
-                        return -errno;
-                if (l != q - w)
-                        return -EIO;
-        }
-
-        return q - (const uint8_t*) p;
-}
diff --git a/src/systemd/src/basic/io-util.h b/src/systemd/src/basic/io-util.h
deleted file mode 100644
index ed189b58..00000000
--- a/src/systemd/src/basic/io-util.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-
-#include "macro.h"
-#include "time-util.h"
-
-int flush_fd(int fd);
-
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
-int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
-int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
-
-int pipe_eof(int fd);
-
-int fd_wait_for_event(int fd, int event, usec_t timeout);
-
-ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
-
-static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, size_t n) {
-        size_t j, r = 0;
-
-        for (j = 0; j < n; j++)
-                r += i[j].iov_len;
-
-        return r;
-}
-
-static inline size_t IOVEC_INCREMENT(struct iovec *i, size_t n, size_t k) {
-        size_t j;
-
-        for (j = 0; j < n; j++) {
-                size_t sub;
-
-                if (_unlikely_(k <= 0))
-                        break;
-
-                sub = MIN(i[j].iov_len, k);
-                i[j].iov_len -= sub;
-                i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
-                k -= sub;
-        }
-
-        return k;
-}
-
-static inline bool FILE_SIZE_VALID(uint64_t l) {
-        /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than
-         * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */
-
-        return (l >> 63) == 0;
-}
-
-static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) {
-
-        /* Same as above, but allows one extra value: -1 as indication for infinity. */
-
-        if (l == (uint64_t) -1)
-                return true;
-
-        return FILE_SIZE_VALID(l);
-
-}
-
-#define IOVEC_INIT(base, len) { .iov_base = (base), .iov_len = (len) }
-#define IOVEC_MAKE(base, len) (struct iovec) IOVEC_INIT(base, len)
-#define IOVEC_INIT_STRING(string) IOVEC_INIT((char*) string, strlen(string))
-#define IOVEC_MAKE_STRING(string) (struct iovec) IOVEC_INIT_STRING(string)
diff --git a/src/systemd/src/basic/list.h b/src/systemd/src/basic/list.h
deleted file mode 100644
index 643e0bea..00000000
--- a/src/systemd/src/basic/list.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-/* The head of the linked list. Use this in the structure that shall
- * contain the head of the linked list */
-#define LIST_HEAD(t,name)                                               \
-        t *name
-
-/* The pointers in the linked list's items. Use this in the item structure */
-#define LIST_FIELDS(t,name)                                             \
-        t *name##_next, *name##_prev
-
-/* Initialize the list's head */
-#define LIST_HEAD_INIT(head)                                            \
-        do {                                                            \
-                (head) = NULL; }                                        \
-        while (false)
-
-/* Initialize a list item */
-#define LIST_INIT(name,item)                                            \
-        do {                                                            \
-                typeof(*(item)) *_item = (item);                        \
-                assert(_item);                                          \
-                _item->name##_prev = _item->name##_next = NULL;         \
-        } while (false)
-
-/* Prepend an item to the list */
-#define LIST_PREPEND(name,head,item)                                    \
-        do {                                                            \
-                typeof(*(head)) **_head = &(head), *_item = (item);     \
-                assert(_item);                                          \
-                if ((_item->name##_next = *_head))                      \
-                        _item->name##_next->name##_prev = _item;        \
-                _item->name##_prev = NULL;                              \
-                *_head = _item;                                         \
-        } while (false)
-
-/* Append an item to the list */
-#define LIST_APPEND(name,head,item)                                     \
-        do {                                                            \
-                typeof(*(head)) *_tail;                                 \
-                LIST_FIND_TAIL(name,head,_tail);                        \
-                LIST_INSERT_AFTER(name,head,_tail,item);                \
-        } while (false)
-
-/* Remove an item from the list */
-#define LIST_REMOVE(name,head,item)                                     \
-        do {                                                            \
-                typeof(*(head)) **_head = &(head), *_item = (item);     \
-                assert(_item);                                          \
-                if (_item->name##_next)                                 \
-                        _item->name##_next->name##_prev = _item->name##_prev; \
-                if (_item->name##_prev)                                 \
-                        _item->name##_prev->name##_next = _item->name##_next; \
-                else {                                                  \
-                        assert(*_head == _item);                        \
-                        *_head = _item->name##_next;                    \
-                }                                                       \
-                _item->name##_next = _item->name##_prev = NULL;         \
-        } while (false)
-
-/* Find the head of the list */
-#define LIST_FIND_HEAD(name,item,head)                                  \
-        do {                                                            \
-                typeof(*(item)) *_item = (item);                        \
-                if (!_item)                                             \
-                        (head) = NULL;                                  \
-                else {                                                  \
-                        while (_item->name##_prev)                      \
-                                _item = _item->name##_prev;             \
-                        (head) = _item;                                 \
-                }                                                       \
-        } while (false)
-
-/* Find the tail of the list */
-#define LIST_FIND_TAIL(name,item,tail)                                  \
-        do {                                                            \
-                typeof(*(item)) *_item = (item);                        \
-                if (!_item)                                             \
-                        (tail) = NULL;                                  \
-                else {                                                  \
-                        while (_item->name##_next)                      \
-                                _item = _item->name##_next;             \
-                        (tail) = _item;                                 \
-                }                                                       \
-        } while (false)
-
-/* Insert an item after another one (a = where, b = what) */
-#define LIST_INSERT_AFTER(name,head,a,b)                                \
-        do {                                                            \
-                typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
-                assert(_b);                                             \
-                if (!_a) {                                              \
-                        if ((_b->name##_next = *_head))                 \
-                                _b->name##_next->name##_prev = _b;      \
-                        _b->name##_prev = NULL;                         \
-                        *_head = _b;                                    \
-                } else {                                                \
-                        if ((_b->name##_next = _a->name##_next))        \
-                                _b->name##_next->name##_prev = _b;      \
-                        _b->name##_prev = _a;                           \
-                        _a->name##_next = _b;                           \
-                }                                                       \
-        } while (false)
-
-/* Insert an item before another one (a = where, b = what) */
-#define LIST_INSERT_BEFORE(name,head,a,b)                               \
-        do {                                                            \
-                typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
-                assert(_b);                                             \
-                if (!_a) {                                              \
-                        if (!*_head) {                                  \
-                                _b->name##_next = NULL;                 \
-                                _b->name##_prev = NULL;                 \
-                                *_head = _b;                            \
-                        } else {                                        \
-                                typeof(*(head)) *_tail = (head);        \
-                                while (_tail->name##_next)              \
-                                        _tail = _tail->name##_next;     \
-                                _b->name##_next = NULL;                 \
-                                _b->name##_prev = _tail;                \
-                                _tail->name##_next = _b;                \
-                        }                                               \
-                } else {                                                \
-                        if ((_b->name##_prev = _a->name##_prev))        \
-                                _b->name##_prev->name##_next = _b;      \
-                        else                                            \
-                                *_head = _b;                            \
-                        _b->name##_next = _a;                           \
-                        _a->name##_prev = _b;                           \
-                }                                                       \
-        } while (false)
-
-#define LIST_JUST_US(name,item)                                         \
-        (!(item)->name##_prev && !(item)->name##_next)                  \
-
-#define LIST_FOREACH(name,i,head)                                       \
-        for ((i) = (head); (i); (i) = (i)->name##_next)
-
-#define LIST_FOREACH_SAFE(name,i,n,head)                                \
-        for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
-
-#define LIST_FOREACH_BEFORE(name,i,p)                                   \
-        for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev)
-
-#define LIST_FOREACH_AFTER(name,i,p)                                    \
-        for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
-
-/* Iterate through all the members of the list p is included in, but skip over p */
-#define LIST_FOREACH_OTHERS(name,i,p)                                   \
-        for (({                                                         \
-                (i) = (p);                                              \
-                while ((i) && (i)->name##_prev)                         \
-                        (i) = (i)->name##_prev;                         \
-                if ((i) == (p))                                         \
-                        (i) = (p)->name##_next;                         \
-             });                                                        \
-             (i);                                                       \
-             (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next)
-
-/* Loop starting from p->next until p->prev.
-   p can be adjusted meanwhile. */
-#define LIST_LOOP_BUT_ONE(name,i,head,p)                                \
-        for ((i) = (p)->name##_next ? (p)->name##_next : (head);        \
-             (i) != (p);                                                \
-             (i) = (i)->name##_next ? (i)->name##_next : (head))
-
-#define LIST_IS_EMPTY(head)                                             \
-        (!(head))
diff --git a/src/systemd/src/basic/log.h b/src/systemd/src/basic/log.h
deleted file mode 100644
index 28edd572..00000000
--- a/src/systemd/src/basic/log.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include "macro.h"
-
-/* Some structures we reference but don't want to pull in headers for */
-struct iovec;
-struct signalfd_siginfo;
-
-typedef enum LogRealm {
-        LOG_REALM_SYSTEMD,
-        LOG_REALM_UDEV,
-        _LOG_REALM_MAX,
-} LogRealm;
-
-#ifndef LOG_REALM
-#  define LOG_REALM LOG_REALM_SYSTEMD
-#endif
-
-typedef enum LogTarget{
-        LOG_TARGET_CONSOLE,
-        LOG_TARGET_CONSOLE_PREFIXED,
-        LOG_TARGET_KMSG,
-        LOG_TARGET_JOURNAL,
-        LOG_TARGET_JOURNAL_OR_KMSG,
-        LOG_TARGET_SYSLOG,
-        LOG_TARGET_SYSLOG_OR_KMSG,
-        LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */
-        LOG_TARGET_NULL,
-        _LOG_TARGET_MAX,
-        _LOG_TARGET_INVALID = -1
-} LogTarget;
-
-#define LOG_REALM_PLUS_LEVEL(realm, level)      \
-        ((realm) << 10 | (level))
-#define LOG_REALM_REMOVE_LEVEL(realm_level)     \
-        ((realm_level >> 10))
-
-void log_set_target(LogTarget target);
-void log_set_max_level_realm(LogRealm realm, int level);
-#define log_set_max_level(level)                \
-        log_set_max_level_realm(LOG_REALM, (level))
-
-void log_set_facility(int facility);
-
-int log_set_target_from_string(const char *e);
-int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
-#define log_set_max_level_from_string(e)        \
-        log_set_max_level_from_string_realm(LOG_REALM, (e))
-
-void log_show_color(bool b);
-bool log_get_show_color(void) _pure_;
-void log_show_location(bool b);
-bool log_get_show_location(void) _pure_;
-
-int log_show_color_from_string(const char *e);
-int log_show_location_from_string(const char *e);
-
-LogTarget log_get_target(void) _pure_;
-#if 0 /* NM_IGNORED */
-int log_get_max_level_realm(LogRealm realm) _pure_;
-#endif /* NM_IGNORED */
-#define log_get_max_level()                     \
-        log_get_max_level_realm(LOG_REALM)
-
-/* Functions below that open and close logs or configure logging based on the
- * environment should not be called from library code — this is always a job
- * for the application itself.
- */
-
-int log_open(void);
-void log_close(void);
-void log_forget_fds(void);
-
-void log_parse_environment_realm(LogRealm realm);
-#define log_parse_environment() \
-        log_parse_environment_realm(LOG_REALM)
-
-#if 0 /* NM_IGNORED */
-int log_dispatch_internal(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *object_field,
-                const char *object,
-                const char *extra,
-                const char *extra_field,
-                char *buffer);
-
-int log_internal_realm(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *format, ...) _printf_(6,7);
-#endif /* NM_IGNORED */
-#define log_internal(level, ...) \
-        log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
-
-#if 0 /* NM_IGNORED */
-int log_internalv_realm(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *format,
-                va_list ap) _printf_(6,0);
-#define log_internalv(level, ...) \
-        log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
-
-/* Realm is fixed to LOG_REALM_SYSTEMD for those */
-int log_object_internal(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *object_field,
-                const char *object,
-                const char *extra_field,
-                const char *extra,
-                const char *format, ...) _printf_(10,11);
-
-int log_struct_internal(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *format, ...) _printf_(6,0) _sentinel_;
-
-int log_oom_internal(
-                LogRealm realm,
-                const char *file,
-                int line,
-                const char *func);
-
-int log_format_iovec(
-                struct iovec *iovec,
-                size_t iovec_len,
-                size_t *n,
-                bool newline_separator,
-                int error,
-                const char *format,
-                va_list ap) _printf_(6, 0);
-
-int log_struct_iovec_internal(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const struct iovec *input_iovec,
-                size_t n_input_iovec);
-
-/* This modifies the buffer passed! */
-int log_dump_internal(
-                int level,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                char *buffer);
-
-/* Logging for various assertions */
-_noreturn_ void log_assert_failed_realm(
-                LogRealm realm,
-                const char *text,
-                const char *file,
-                int line,
-                const char *func);
-#define log_assert_failed(text, ...) \
-        log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
-
-_noreturn_ void log_assert_failed_unreachable_realm(
-                LogRealm realm,
-                const char *text,
-                const char *file,
-                int line,
-                const char *func);
-#define log_assert_failed_unreachable(text, ...) \
-        log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
-
-void log_assert_failed_return_realm(
-                LogRealm realm,
-                const char *text,
-                const char *file,
-                int line,
-                const char *func);
-#define log_assert_failed_return(text, ...) \
-        log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
-
-#define log_dispatch(level, error, buffer)                              \
-        log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
-#endif /* NM_IGNORED */
-
-/* Logging with level */
-#define log_full_errno_realm(realm, level, error, ...)                  \
-        ({                                                              \
-                int _level = (level), _e = (error), _realm = (realm);   \
-                (log_get_max_level_realm(_realm) >= LOG_PRI(_level))   \
-                        ? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \
-                                             __FILE__, __LINE__, __func__, __VA_ARGS__) \
-                        : -abs(_e);                                     \
-        })
-
-#define log_full_errno(level, error, ...)                               \
-        log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
-
-#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
-
-int log_emergency_level(void);
-
-/* Normal logging */
-#define log_debug(...)     log_full(LOG_DEBUG,   __VA_ARGS__)
-#define log_info(...)      log_full(LOG_INFO,    __VA_ARGS__)
-#define log_notice(...)    log_full(LOG_NOTICE,  __VA_ARGS__)
-#define log_warning(...)   log_full(LOG_WARNING, __VA_ARGS__)
-#define log_error(...)     log_full(LOG_ERR,     __VA_ARGS__)
-#define log_emergency(...) log_full(log_emergency_level(), __VA_ARGS__)
-
-/* Logging triggered by an errno-like error */
-#define log_debug_errno(error, ...)     log_full_errno(LOG_DEBUG,   error, __VA_ARGS__)
-#define log_info_errno(error, ...)      log_full_errno(LOG_INFO,    error, __VA_ARGS__)
-#define log_notice_errno(error, ...)    log_full_errno(LOG_NOTICE,  error, __VA_ARGS__)
-#define log_warning_errno(error, ...)   log_full_errno(LOG_WARNING, error, __VA_ARGS__)
-#define log_error_errno(error, ...)     log_full_errno(LOG_ERR,     error, __VA_ARGS__)
-#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
-
-#ifdef LOG_TRACE
-#  define log_trace(...) log_debug(__VA_ARGS__)
-#else
-#  define log_trace(...) do {} while (0)
-#endif
-
-/* Structured logging */
-#define log_struct_errno(level, error, ...) \
-        log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
-                            error, __FILE__, __LINE__, __func__, __VA_ARGS__, NULL)
-#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
-
-#define log_struct_iovec_errno(level, error, iovec, n_iovec)            \
-        log_struct_iovec_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
-                                  error, __FILE__, __LINE__, __func__, iovec, n_iovec)
-#define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec)
-
-/* This modifies the buffer passed! */
-#define log_dump(level, buffer) \
-        log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
-                          0, __FILE__, __LINE__, __func__, buffer)
-
-#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
-
-bool log_on_console(void) _pure_;
-
-const char *log_target_to_string(LogTarget target) _const_;
-LogTarget log_target_from_string(const char *s) _pure_;
-
-/* Helper to prepare various field for structured logging */
-#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
-
-void log_received_signal(int level, const struct signalfd_siginfo *si);
-
-/* If turned on, any requests for a log target involving "syslog" will be implicitly upgraded to the equivalent journal target */
-void log_set_upgrade_syslog_to_journal(bool b);
-
-/* If turned on, and log_open() is called, we'll not use STDERR_FILENO for logging ever, but rather open /dev/console */
-void log_set_always_reopen_console(bool b);
-
-/* If turned on, we'll open the log stream implicitly if needed on each individual log call. This is normally not
- * desired as we want to reuse our logging streams. It is useful however  */
-void log_set_open_when_needed(bool b);
-
-/* If turned on, then we'll never use IPC-based logging, i.e. never log to syslog or the journal. We'll only log to
- * stderr, the console or kmsg */
-void log_set_prohibit_ipc(bool b);
-
-int log_dup_console(void);
-
-int log_syntax_internal(
-                const char *unit,
-                int level,
-                const char *config_file,
-                unsigned config_line,
-                int error,
-                const char *file,
-                int line,
-                const char *func,
-                const char *format, ...) _printf_(9, 10);
-
-int log_syntax_invalid_utf8_internal(
-                const char *unit,
-                int level,
-                const char *config_file,
-                unsigned config_line,
-                const char *file,
-                int line,
-                const char *func,
-                const char *rvalue);
-
-#define log_syntax(unit, level, config_file, config_line, error, ...)   \
-        ({                                                              \
-                int _level = (level), _e = (error);                     \
-                (log_get_max_level() >= LOG_PRI(_level))                \
-                        ? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
-                        : -abs(_e);                                     \
-        })
-
-#define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \
-        ({                                                              \
-                int _level = (level);                                   \
-                (log_get_max_level() >= LOG_PRI(_level))                \
-                        ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, __FILE__, __LINE__, __func__, rvalue) \
-                        : -EINVAL;                                      \
-        })
-
-#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h
deleted file mode 100644
index 22193fe3..00000000
--- a/src/systemd/src/basic/macro.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <inttypes.h>
-#include <stdbool.h>
-#include <sys/param.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-
-#define _printf_(a, b) __attribute__ ((format (printf, a, b)))
-#ifdef __clang__
-#  define _alloc_(...)
-#else
-#  define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
-#endif
-#define _sentinel_ __attribute__ ((sentinel))
-#define _unused_ __attribute__ ((unused))
-#define _destructor_ __attribute__ ((destructor))
-#define _pure_ __attribute__ ((pure))
-#define _const_ __attribute__ ((const))
-#define _deprecated_ __attribute__ ((deprecated))
-#define _packed_ __attribute__ ((packed))
-#define _malloc_ __attribute__ ((malloc))
-#define _weak_ __attribute__ ((weak))
-#define _likely_(x) (__builtin_expect(!!(x), 1))
-#define _unlikely_(x) (__builtin_expect(!!(x), 0))
-#define _public_ __attribute__ ((visibility("default")))
-#define _hidden_ __attribute__ ((visibility("hidden")))
-#define _weakref_(x) __attribute__((weakref(#x)))
-#define _alignas_(x) __attribute__((aligned(__alignof(x))))
-#define _cleanup_(x) __attribute__((cleanup(x)))
-#if __GNUC__ >= 7
-#define _fallthrough_ __attribute__((fallthrough))
-#else
-#define _fallthrough_
-#endif
-/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
- * compiler versions */
-#ifndef _noreturn_
-#if __STDC_VERSION__ >= 201112L
-#define _noreturn_ _Noreturn
-#else
-#define _noreturn_ __attribute__((noreturn))
-#endif
-#endif
-
-#if !defined(HAS_FEATURE_MEMORY_SANITIZER)
-#  if defined(__has_feature)
-#    if __has_feature(memory_sanitizer)
-#      define HAS_FEATURE_MEMORY_SANITIZER 1
-#    endif
-#  endif
-#  if !defined(HAS_FEATURE_MEMORY_SANITIZER)
-#    define HAS_FEATURE_MEMORY_SANITIZER 0
-#  endif
-#endif
-
-#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined (__clang__)
-/* Temporarily disable some warnings */
-#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT                     \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
-
-#define DISABLE_WARNING_FORMAT_NONLITERAL                               \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
-
-#define DISABLE_WARNING_MISSING_PROTOTYPES                              \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
-
-#define DISABLE_WARNING_NONNULL                                         \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
-
-#define DISABLE_WARNING_SHADOW                                          \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wshadow\"")
-
-#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES                      \
-        _Pragma("GCC diagnostic push");                                 \
-        _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"")
-
-#define REENABLE_WARNING                                                \
-        _Pragma("GCC diagnostic pop")
-#else
-#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT
-#define DISABLE_WARNING_FORMAT_NONLITERAL
-#define DISABLE_WARNING_MISSING_PROTOTYPES
-#define DISABLE_WARNING_NONNULL
-#define DISABLE_WARNING_SHADOW
-#define REENABLE_WARNING
-#endif
-
-/* automake test harness */
-#define EXIT_TEST_SKIP 77
-
-#define XSTRINGIFY(x) #x
-#define STRINGIFY(x) XSTRINGIFY(x)
-
-#define XCONCATENATE(x, y) x ## y
-#define CONCATENATE(x, y) XCONCATENATE(x, y)
-
-#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
-#define UNIQ __COUNTER__
-
-/* builtins */
-#if __SIZEOF_INT__ == 4
-#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
-#elif __SIZEOF_LONG__ == 4
-#define BUILTIN_FFS_U32(x) __builtin_ffsl(x);
-#else
-#error "neither int nor long are four bytes long?!?"
-#endif
-
-/* Rounds up */
-
-#define ALIGN4(l) (((l) + 3) & ~3)
-#define ALIGN8(l) (((l) + 7) & ~7)
-
-#if __SIZEOF_POINTER__ == 8
-#define ALIGN(l) ALIGN8(l)
-#elif __SIZEOF_POINTER__ == 4
-#define ALIGN(l) ALIGN4(l)
-#else
-#error "Wut? Pointers are neither 4 nor 8 bytes long?"
-#endif
-
-#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p)))
-#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
-#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
-
-static inline size_t ALIGN_TO(size_t l, size_t ali) {
-        return ((l + ali - 1) & ~(ali - 1));
-}
-
-#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
-
-/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
-static inline unsigned long ALIGN_POWER2(unsigned long u) {
-        /* clz(0) is undefined */
-        if (u == 1)
-                return 1;
-
-        /* left-shift overflow is undefined */
-        if (__builtin_clzl(u - 1UL) < 1)
-                return 0;
-
-        return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
-}
-
-#ifndef __COVERITY__
-#  define VOID_0 ((void)0)
-#else
-#  define VOID_0 ((void*)0)
-#endif
-
-#define ELEMENTSOF(x)                                                   \
-        (__builtin_choose_expr(                                         \
-                !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
-                sizeof(x)/sizeof((x)[0]),                               \
-                VOID_0))
-
-/*
- * STRLEN - return the length of a string literal, minus the trailing NUL byte.
- *          Contrary to strlen(), this is a constant expression.
- * @x: a string literal.
- */
-#define STRLEN(x) (sizeof(""x"") - 1)
-
-/*
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- */
-#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
-#define __container_of(uniq, ptr, type, member)                         \
-        ({                                                              \
-                const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
-                (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \
-        })
-
-#undef MAX
-#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
-#define __MAX(aq, a, bq, b)                             \
-        ({                                              \
-                const typeof(a) UNIQ_T(A, aq) = (a);    \
-                const typeof(b) UNIQ_T(B, bq) = (b);    \
-                UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
-        })
-
-/* evaluates to (void) if _A or _B are not constant or of different types */
-#define CONST_MAX(_A, _B) \
-        (__builtin_choose_expr(                                         \
-                __builtin_constant_p(_A) &&                             \
-                __builtin_constant_p(_B) &&                             \
-                __builtin_types_compatible_p(typeof(_A), typeof(_B)),   \
-                ((_A) > (_B)) ? (_A) : (_B),                            \
-                VOID_0))
-
-/* takes two types and returns the size of the larger one */
-#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
-
-#define MAX3(x, y, z)                                   \
-        ({                                              \
-                const typeof(x) _c = MAX(x, y);         \
-                MAX(_c, z);                             \
-        })
-
-#undef MIN
-#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
-#define __MIN(aq, a, bq, b)                             \
-        ({                                              \
-                const typeof(a) UNIQ_T(A, aq) = (a);    \
-                const typeof(b) UNIQ_T(B, bq) = (b);    \
-                UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
-        })
-
-#define MIN3(x, y, z)                                   \
-        ({                                              \
-                const typeof(x) _c = MIN(x, y);         \
-                MIN(_c, z);                             \
-        })
-
-#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
-#define __LESS_BY(aq, a, bq, b)                         \
-        ({                                              \
-                const typeof(a) UNIQ_T(A, aq) = (a);    \
-                const typeof(b) UNIQ_T(B, bq) = (b);    \
-                UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \
-        })
-
-#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b))
-#define __CMP(aq, a, bq, b)                             \
-        ({                                              \
-                const typeof(a) UNIQ_T(A, aq) = (a);    \
-                const typeof(b) UNIQ_T(B, bq) = (b);    \
-                UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 :    \
-                UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0;  \
-        })
-
-#undef CLAMP
-#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
-#define __CLAMP(xq, x, lowq, low, highq, high)                          \
-        ({                                                              \
-                const typeof(x) UNIQ_T(X, xq) = (x);                    \
-                const typeof(low) UNIQ_T(LOW, lowq) = (low);            \
-                const typeof(high) UNIQ_T(HIGH, highq) = (high);        \
-                        UNIQ_T(X, xq) > UNIQ_T(HIGH, highq) ?           \
-                                UNIQ_T(HIGH, highq) :                   \
-                                UNIQ_T(X, xq) < UNIQ_T(LOW, lowq) ?     \
-                                        UNIQ_T(LOW, lowq) :             \
-                                        UNIQ_T(X, xq);                  \
-        })
-
-/* [(x + y - 1) / y] suffers from an integer overflow, even though the
- * computation should be possible in the given type. Therefore, we use
- * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
- * quotient and the remainder, so both should be equally fast. */
-#define DIV_ROUND_UP(_x, _y)                                            \
-        ({                                                              \
-                const typeof(_x) __x = (_x);                            \
-                const typeof(_y) __y = (_y);                            \
-                (__x / __y + !!(__x % __y));                            \
-        })
-
-#ifdef __COVERITY__
-
-/* Use special definitions of assertion macros in order to prevent
- * false positives of ASSERT_SIDE_EFFECT on Coverity static analyzer
- * for uses of assert_se() and assert_return().
- *
- * These definitions make expression go through a (trivial) function
- * call to ensure they are not discarded. Also use ! or !! to ensure
- * the boolean expressions are seen as such.
- *
- * This technique has been described and recommended in:
- * https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects
- */
-
-extern void __coverity_panic__(void);
-
-static inline int __coverity_check__(int condition) {
-        return condition;
-}
-
-#define assert_message_se(expr, message)                                \
-        do {                                                            \
-                if (__coverity_check__(!(expr)))                        \
-                        __coverity_panic__();                           \
-        } while (false)
-
-#define assert_log(expr, message) __coverity_check__(!!(expr))
-
-#else  /* ! __COVERITY__ */
-
-#define assert_message_se(expr, message)                                \
-        do {                                                            \
-                if (_unlikely_(!(expr)))                                \
-                        log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
-        } while (false)
-
-#define assert_log(expr, message) ((_likely_(expr))                     \
-        ? (true)                                                        \
-        : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
-
-#endif  /* __COVERITY__ */
-
-#define assert_se(expr) assert_message_se(expr, #expr)
-
-/* We override the glibc assert() here. */
-#undef assert
-#ifdef NDEBUG
-#define assert(expr) do {} while (false)
-#else
-#define assert(expr) assert_message_se(expr, #expr)
-#endif
-
-#define assert_not_reached(t)                                           \
-        do {                                                            \
-                log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
-        } while (false)
-
-#if defined(static_assert)
-/* static_assert() is sometimes defined in a way that trips up
- * -Wdeclaration-after-statement, hence let's temporarily turn off
- * this warning around it. */
-#define assert_cc(expr)                                                 \
-        DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \
-        static_assert(expr, #expr);                                     \
-        REENABLE_WARNING
-#else
-#define assert_cc(expr)                                                 \
-        DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \
-        struct CONCATENATE(_assert_struct_, __COUNTER__) {              \
-                char x[(expr) ? 0 : -1];                                \
-        };                                                              \
-        REENABLE_WARNING
-#endif
-
-#define assert_return(expr, r)                                          \
-        do {                                                            \
-                if (!assert_log(expr, #expr))                           \
-                        return (r);                                     \
-        } while (false)
-
-#define assert_return_errno(expr, r, err)                               \
-        do {                                                            \
-                if (!assert_log(expr, #expr)) {                         \
-                        errno = err;                                    \
-                        return (r);                                     \
-                }                                                       \
-        } while (false)
-
-#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
-#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
-#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
-#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
-
-#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
-#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
-#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
-#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
-
-#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
-#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
-#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
-#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
-
-#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
-#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
-#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
-#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
-
-#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
-#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
-
-#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
-
-#define char_array_0(x) x[sizeof(x)-1] = 0;
-
-/* Returns the number of chars needed to format variables of the
- * specified type as a decimal string. Adds in extra space for a
- * negative '-' prefix (hence works correctly on signed
- * types). Includes space for the trailing NUL. */
-#define DECIMAL_STR_MAX(type)                                           \
-        (2+(sizeof(type) <= 1 ? 3 :                                     \
-            sizeof(type) <= 2 ? 5 :                                     \
-            sizeof(type) <= 4 ? 10 :                                    \
-            sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
-
-#define DECIMAL_STR_WIDTH(x)                            \
-        ({                                              \
-                typeof(x) _x_ = (x);                    \
-                unsigned ans = 1;                       \
-                while ((_x_ /= 10) != 0)                \
-                        ans++;                          \
-                ans;                                    \
-        })
-
-#define SET_FLAG(v, flag, b) \
-        (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
-#define FLAGS_SET(v, flags) \
-        (((v) & (flags)) == (flags))
-
-#define CASE_F(X) case X:
-#define CASE_F_1(CASE, X) CASE_F(X)
-#define CASE_F_2(CASE, X, ...)  CASE(X) CASE_F_1(CASE, __VA_ARGS__)
-#define CASE_F_3(CASE, X, ...)  CASE(X) CASE_F_2(CASE, __VA_ARGS__)
-#define CASE_F_4(CASE, X, ...)  CASE(X) CASE_F_3(CASE, __VA_ARGS__)
-#define CASE_F_5(CASE, X, ...)  CASE(X) CASE_F_4(CASE, __VA_ARGS__)
-#define CASE_F_6(CASE, X, ...)  CASE(X) CASE_F_5(CASE, __VA_ARGS__)
-#define CASE_F_7(CASE, X, ...)  CASE(X) CASE_F_6(CASE, __VA_ARGS__)
-#define CASE_F_8(CASE, X, ...)  CASE(X) CASE_F_7(CASE, __VA_ARGS__)
-#define CASE_F_9(CASE, X, ...)  CASE(X) CASE_F_8(CASE, __VA_ARGS__)
-#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__)
-#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__)
-#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__)
-#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__)
-#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__)
-#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__)
-#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__)
-#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__)
-#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__)
-#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__)
-#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__)
-
-#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME
-#define FOR_EACH_MAKE_CASE(...) \
-        GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \
-                               CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \
-                   (CASE_F,__VA_ARGS__)
-
-#define IN_SET(x, ...)                          \
-        ({                                      \
-                bool _found = false;            \
-                /* If the build breaks in the line below, you need to extend the case macros */ \
-                static _unused_ char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \
-                switch(x) {                     \
-                FOR_EACH_MAKE_CASE(__VA_ARGS__) \
-                        _found = true;          \
-                        break;                  \
-                default:                        \
-                        break;                  \
-                }                               \
-                _found;                         \
-        })
-
-#define SWAP_TWO(x, y) do {                        \
-                typeof(x) _t = (x);                \
-                (x) = (y);                         \
-                (y) = (_t);                        \
-        } while (false)
-
-/* Define C11 thread_local attribute even on older gcc compiler
- * version */
-#ifndef thread_local
-/*
- * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
- * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
- */
-#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
-#define thread_local _Thread_local
-#else
-#define thread_local __thread
-#endif
-#endif
-
-#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func)                 \
-        static inline void func##p(type *p) {                   \
-                if (*p)                                         \
-                        func(*p);                               \
-        }
-
-#include "log.h"
diff --git a/src/systemd/src/basic/mempool.c b/src/systemd/src/basic/mempool.c
deleted file mode 100644
index dd1b1e5f..00000000
--- a/src/systemd/src/basic/mempool.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "macro.h"
-#include "mempool.h"
-#include "util.h"
-
-struct pool {
-        struct pool *next;
-        size_t n_tiles;
-        size_t n_used;
-};
-
-void* mempool_alloc_tile(struct mempool *mp) {
-        size_t i;
-
-        /* When a tile is released we add it to the list and simply
-         * place the next pointer at its offset 0. */
-
-        assert(mp->tile_size >= sizeof(void*));
-        assert(mp->at_least > 0);
-
-        if (mp->freelist) {
-                void *r;
-
-                r = mp->freelist;
-                mp->freelist = * (void**) mp->freelist;
-                return r;
-        }
-
-        if (_unlikely_(!mp->first_pool) ||
-            _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) {
-                size_t size, n;
-                struct pool *p;
-
-                n = mp->first_pool ? mp->first_pool->n_tiles : 0;
-                n = MAX(mp->at_least, n * 2);
-                size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size);
-                n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size;
-
-                p = malloc(size);
-                if (!p)
-                        return NULL;
-
-                p->next = mp->first_pool;
-                p->n_tiles = n;
-                p->n_used = 0;
-
-                mp->first_pool = p;
-        }
-
-        i = mp->first_pool->n_used++;
-
-        return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size;
-}
-
-void* mempool_alloc0_tile(struct mempool *mp) {
-        void *p;
-
-        p = mempool_alloc_tile(mp);
-        if (p)
-                memzero(p, mp->tile_size);
-        return p;
-}
-
-void mempool_free_tile(struct mempool *mp, void *p) {
-        * (void**) p = mp->freelist;
-        mp->freelist = p;
-}
-
-#if VALGRIND
-
-void mempool_drop(struct mempool *mp) {
-        struct pool *p = mp->first_pool;
-        while (p) {
-                struct pool *n;
-                n = p->next;
-                free(p);
-                p = n;
-        }
-}
-
-#endif
diff --git a/src/systemd/src/basic/mempool.h b/src/systemd/src/basic/mempool.h
deleted file mode 100644
index 4098535c..00000000
--- a/src/systemd/src/basic/mempool.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stddef.h>
-
-struct pool;
-
-struct mempool {
-        struct pool *first_pool;
-        void *freelist;
-        size_t tile_size;
-        unsigned at_least;
-};
-
-void* mempool_alloc_tile(struct mempool *mp);
-void* mempool_alloc0_tile(struct mempool *mp);
-void mempool_free_tile(struct mempool *mp, void *p);
-
-#define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \
-static struct mempool pool_name = { \
-        .tile_size = sizeof(tile_type), \
-        .at_least = alloc_at_least, \
-}
-
-#if VALGRIND
-void mempool_drop(struct mempool *mp);
-#endif
diff --git a/src/systemd/src/basic/parse-util.c b/src/systemd/src/basic/parse-util.c
deleted file mode 100644
index b0ccce28..00000000
--- a/src/systemd/src/basic/parse-util.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include "alloc-util.h"
-#include "errno-list.h"
-#include "extract-word.h"
-#include "locale-util.h"
-#include "macro.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "process-util.h"
-#include "string-util.h"
-
-int parse_boolean(const char *v) {
-        assert(v);
-
-        if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
-                return 1;
-        else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
-                return 0;
-
-        return -EINVAL;
-}
-
-#if 0 /* NM_IGNORED */
-int parse_pid(const char *s, pid_t* ret_pid) {
-        unsigned long ul = 0;
-        pid_t pid;
-        int r;
-
-        assert(s);
-        assert(ret_pid);
-
-        r = safe_atolu(s, &ul);
-        if (r < 0)
-                return r;
-
-        pid = (pid_t) ul;
-
-        if ((unsigned long) pid != ul)
-                return -ERANGE;
-
-        if (!pid_is_valid(pid))
-                return -ERANGE;
-
-        *ret_pid = pid;
-        return 0;
-}
-
-int parse_mode(const char *s, mode_t *ret) {
-        char *x;
-        long l;
-
-        assert(s);
-        assert(ret);
-
-        s += strspn(s, WHITESPACE);
-        if (s[0] == '-')
-                return -ERANGE;
-
-        errno = 0;
-        l = strtol(s, &x, 8);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if (l < 0 || l  > 07777)
-                return -ERANGE;
-
-        *ret = (mode_t) l;
-        return 0;
-}
-
-int parse_ifindex(const char *s, int *ret) {
-        int ifi, r;
-
-        r = safe_atoi(s, &ifi);
-        if (r < 0)
-                return r;
-        if (ifi <= 0)
-                return -EINVAL;
-
-        *ret = ifi;
-        return 0;
-}
-
-int parse_mtu(int family, const char *s, uint32_t *ret) {
-        uint64_t u;
-        size_t m;
-        int r;
-
-        r = parse_size(s, 1024, &u);
-        if (r < 0)
-                return r;
-
-        if (u > UINT32_MAX)
-                return -ERANGE;
-
-        if (family == AF_INET6)
-                m = IPV6_MIN_MTU; /* This is 1280 */
-        else
-                m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */
-
-        if (u < m)
-                return -ERANGE;
-
-        *ret = (uint32_t) u;
-        return 0;
-}
-
-int parse_size(const char *t, uint64_t base, uint64_t *size) {
-
-        /* Soo, sometimes we want to parse IEC binary suffixes, and
-         * sometimes SI decimal suffixes. This function can parse
-         * both. Which one is the right way depends on the
-         * context. Wikipedia suggests that SI is customary for
-         * hardware metrics and network speeds, while IEC is
-         * customary for most data sizes used by software and volatile
-         * (RAM) memory. Hence be careful which one you pick!
-         *
-         * In either case we use just K, M, G as suffix, and not Ki,
-         * Mi, Gi or so (as IEC would suggest). That's because that's
-         * frickin' ugly. But this means you really need to make sure
-         * to document which base you are parsing when you use this
-         * call. */
-
-        struct table {
-                const char *suffix;
-                unsigned long long factor;
-        };
-
-        static const struct table iec[] = {
-                { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
-                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
-                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
-                { "G", 1024ULL*1024ULL*1024ULL },
-                { "M", 1024ULL*1024ULL },
-                { "K", 1024ULL },
-                { "B", 1ULL },
-                { "",  1ULL },
-        };
-
-        static const struct table si[] = {
-                { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
-                { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
-                { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
-                { "G", 1000ULL*1000ULL*1000ULL },
-                { "M", 1000ULL*1000ULL },
-                { "K", 1000ULL },
-                { "B", 1ULL },
-                { "",  1ULL },
-        };
-
-        const struct table *table;
-        const char *p;
-        unsigned long long r = 0;
-        unsigned n_entries, start_pos = 0;
-
-        assert(t);
-        assert(IN_SET(base, 1000, 1024));
-        assert(size);
-
-        if (base == 1000) {
-                table = si;
-                n_entries = ELEMENTSOF(si);
-        } else {
-                table = iec;
-                n_entries = ELEMENTSOF(iec);
-        }
-
-        p = t;
-        do {
-                unsigned long long l, tmp;
-                double frac = 0;
-                char *e;
-                unsigned i;
-
-                p += strspn(p, WHITESPACE);
-
-                errno = 0;
-                l = strtoull(p, &e, 10);
-                if (errno > 0)
-                        return -errno;
-                if (e == p)
-                        return -EINVAL;
-                if (*p == '-')
-                        return -ERANGE;
-
-                if (*e == '.') {
-                        e++;
-
-                        /* strtoull() itself would accept space/+/- */
-                        if (*e >= '0' && *e <= '9') {
-                                unsigned long long l2;
-                                char *e2;
-
-                                l2 = strtoull(e, &e2, 10);
-                                if (errno > 0)
-                                        return -errno;
-
-                                /* Ignore failure. E.g. 10.M is valid */
-                                frac = l2;
-                                for (; e < e2; e++)
-                                        frac /= 10;
-                        }
-                }
-
-                e += strspn(e, WHITESPACE);
-
-                for (i = start_pos; i < n_entries; i++)
-                        if (startswith(e, table[i].suffix))
-                                break;
-
-                if (i >= n_entries)
-                        return -EINVAL;
-
-                if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
-                        return -ERANGE;
-
-                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
-                if (tmp > ULLONG_MAX - r)
-                        return -ERANGE;
-
-                r += tmp;
-                if ((unsigned long long) (uint64_t) r != r)
-                        return -ERANGE;
-
-                p = e + strlen(table[i].suffix);
-
-                start_pos = i + 1;
-
-        } while (*p);
-
-        *size = r;
-
-        return 0;
-}
-
-int parse_range(const char *t, unsigned *lower, unsigned *upper) {
-        _cleanup_free_ char *word = NULL;
-        unsigned l, u;
-        int r;
-
-        assert(lower);
-        assert(upper);
-
-        /* Extract the lower bound. */
-        r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                return -EINVAL;
-
-        r = safe_atou(word, &l);
-        if (r < 0)
-                return r;
-
-        /* Check for the upper bound and extract it if needed */
-        if (!t)
-                /* Single number with no dashes. */
-                u = l;
-        else if (!*t)
-                /* Trailing dash is an error. */
-                return -EINVAL;
-        else {
-                r = safe_atou(t, &u);
-                if (r < 0)
-                        return r;
-        }
-
-        *lower = l;
-        *upper = u;
-        return 0;
-}
-
-int parse_errno(const char *t) {
-        int r, e;
-
-        assert(t);
-
-        r = errno_from_name(t);
-        if (r > 0)
-                return r;
-
-        r = safe_atoi(t, &e);
-        if (r < 0)
-                return r;
-
-        /* 0 is also allowed here */
-        if (!errno_is_valid(e) && e != 0)
-                return -ERANGE;
-
-        return e;
-}
-
-int parse_syscall_and_errno(const char *in, char **name, int *error) {
-        _cleanup_free_ char *n = NULL;
-        char *p;
-        int e = -1;
-
-        assert(in);
-        assert(name);
-        assert(error);
-
-        /*
-         * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255".
-         * If errno is omitted, then error is set to -1.
-         * Empty syscall name is not allowed.
-         * Here, we do not check that the syscall name is valid or not.
-         */
-
-        p = strchr(in, ':');
-        if (p) {
-                e = parse_errno(p + 1);
-                if (e < 0)
-                        return e;
-
-                n = strndup(in, p - in);
-        } else
-                n = strdup(in);
-
-        if (!n)
-                return -ENOMEM;
-
-        if (isempty(n))
-                return -EINVAL;
-
-        *error = e;
-        *name = TAKE_PTR(n);
-
-        return 0;
-}
-
-char *format_bytes(char *buf, size_t l, uint64_t t) {
-        unsigned i;
-
-        /* This only does IEC units so far */
-
-        static const struct {
-                const char *suffix;
-                uint64_t factor;
-        } table[] = {
-                { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
-                { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
-                { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
-                { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
-                { "M", UINT64_C(1024)*UINT64_C(1024) },
-                { "K", UINT64_C(1024) },
-        };
-
-        if (t == (uint64_t) -1)
-                return NULL;
-
-        for (i = 0; i < ELEMENTSOF(table); i++) {
-
-                if (t >= table[i].factor) {
-                        snprintf(buf, l,
-                                 "%" PRIu64 ".%" PRIu64 "%s",
-                                 t / table[i].factor,
-                                 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
-                                 table[i].suffix);
-
-                        goto finish;
-                }
-        }
-
-        snprintf(buf, l, "%" PRIu64 "B", t);
-
-finish:
-        buf[l-1] = 0;
-        return buf;
-
-}
-#endif /* NM_IGNORED */
-
-int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
-        char *x = NULL;
-        unsigned long l;
-
-        assert(s);
-        assert(ret_u);
-        assert(base <= 16);
-
-        /* strtoul() is happy to parse negative values, and silently
-         * converts them to unsigned values without generating an
-         * error. We want a clean error, hence let's look for the "-"
-         * prefix on our own, and generate an error. But let's do so
-         * only after strtoul() validated that the string is clean
-         * otherwise, so that we return EINVAL preferably over
-         * ERANGE. */
-
-        s += strspn(s, WHITESPACE);
-
-        errno = 0;
-        l = strtoul(s, &x, base);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if (s[0] == '-')
-                return -ERANGE;
-        if ((unsigned long) (unsigned) l != l)
-                return -ERANGE;
-
-        *ret_u = (unsigned) l;
-        return 0;
-}
-
-int safe_atoi(const char *s, int *ret_i) {
-        char *x = NULL;
-        long l;
-
-        assert(s);
-        assert(ret_i);
-
-        errno = 0;
-        l = strtol(s, &x, 0);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if ((long) (int) l != l)
-                return -ERANGE;
-
-        *ret_i = (int) l;
-        return 0;
-}
-
-int safe_atollu(const char *s, long long unsigned *ret_llu) {
-        char *x = NULL;
-        unsigned long long l;
-
-        assert(s);
-        assert(ret_llu);
-
-        s += strspn(s, WHITESPACE);
-
-        errno = 0;
-        l = strtoull(s, &x, 0);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if (*s == '-')
-                return -ERANGE;
-
-        *ret_llu = l;
-        return 0;
-}
-
-int safe_atolli(const char *s, long long int *ret_lli) {
-        char *x = NULL;
-        long long l;
-
-        assert(s);
-        assert(ret_lli);
-
-        errno = 0;
-        l = strtoll(s, &x, 0);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-
-        *ret_lli = l;
-        return 0;
-}
-
-int safe_atou8(const char *s, uint8_t *ret) {
-        char *x = NULL;
-        unsigned long l;
-
-        assert(s);
-        assert(ret);
-
-        s += strspn(s, WHITESPACE);
-
-        errno = 0;
-        l = strtoul(s, &x, 0);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if (s[0] == '-')
-                return -ERANGE;
-        if ((unsigned long) (uint8_t) l != l)
-                return -ERANGE;
-
-        *ret = (uint8_t) l;
-        return 0;
-}
-
-int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
-        char *x = NULL;
-        unsigned long l;
-
-        assert(s);
-        assert(ret);
-        assert(base <= 16);
-
-        s += strspn(s, WHITESPACE);
-
-        errno = 0;
-        l = strtoul(s, &x, base);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if (s[0] == '-')
-                return -ERANGE;
-        if ((unsigned long) (uint16_t) l != l)
-                return -ERANGE;
-
-        *ret = (uint16_t) l;
-        return 0;
-}
-
-int safe_atoi16(const char *s, int16_t *ret) {
-        char *x = NULL;
-        long l;
-
-        assert(s);
-        assert(ret);
-
-        errno = 0;
-        l = strtol(s, &x, 0);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-        if ((long) (int16_t) l != l)
-                return -ERANGE;
-
-        *ret = (int16_t) l;
-        return 0;
-}
-
-#if 0 /* NM_IGNORED */
-int safe_atod(const char *s, double *ret_d) {
-        _cleanup_(freelocalep) locale_t loc = (locale_t) 0;
-        char *x = NULL;
-        double d = 0;
-
-        assert(s);
-        assert(ret_d);
-
-        loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
-        if (loc == (locale_t) 0)
-                return -errno;
-
-        errno = 0;
-        d = strtod_l(s, &x, loc);
-        if (errno > 0)
-                return -errno;
-        if (!x || x == s || *x != 0)
-                return -EINVAL;
-
-        *ret_d = (double) d;
-        return 0;
-}
-
-int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
-        size_t i;
-        unsigned val = 0;
-        const char *s;
-
-        s = *p;
-
-        /* accept any number of digits, strtoull is limted to 19 */
-        for (i=0; i < digits; i++,s++) {
-                if (*s < '0' || *s > '9') {
-                        if (i == 0)
-                                return -EINVAL;
-
-                        /* too few digits, pad with 0 */
-                        for (; i < digits; i++)
-                                val *= 10;
-
-                        break;
-                }
-
-                val *= 10;
-                val += *s - '0';
-        }
-
-        /* maybe round up */
-        if (*s >= '5' && *s <= '9')
-                val++;
-
-        s += strspn(s, DIGITS);
-
-        *p = s;
-        *res = val;
-
-        return 0;
-}
-
-int parse_percent_unbounded(const char *p) {
-        const char *pc, *n;
-        int r, v;
-
-        pc = endswith(p, "%");
-        if (!pc)
-                return -EINVAL;
-
-        n = strndupa(p, pc - p);
-        r = safe_atoi(n, &v);
-        if (r < 0)
-                return r;
-        if (v < 0)
-                return -ERANGE;
-
-        return v;
-}
-
-int parse_percent(const char *p) {
-        int v;
-
-        v = parse_percent_unbounded(p);
-        if (v > 100)
-                return -ERANGE;
-
-        return v;
-}
-
-int parse_permille_unbounded(const char *p) {
-        const char *pc, *pm, *dot, *n;
-        int r, q, v;
-
-        pm = endswith(p, "‰");
-        if (pm) {
-                n = strndupa(p, pm - p);
-                r = safe_atoi(n, &v);
-                if (r < 0)
-                        return r;
-                if (v < 0)
-                        return -ERANGE;
-        } else {
-                pc = endswith(p, "%");
-                if (!pc)
-                        return -EINVAL;
-
-                dot = memchr(p, '.', pc - p);
-                if (dot) {
-                        if (dot + 2 != pc)
-                                return -EINVAL;
-                        if (dot[1] < '0' || dot[1] > '9')
-                                return -EINVAL;
-                        q = dot[1] - '0';
-                        n = strndupa(p, dot - p);
-                } else {
-                        q = 0;
-                        n = strndupa(p, pc - p);
-                }
-                r = safe_atoi(n, &v);
-                if (r < 0)
-                        return r;
-                if (v < 0)
-                        return -ERANGE;
-                if (v > (INT_MAX - q) / 10)
-                        return -ERANGE;
-
-                v = v * 10 + q;
-        }
-
-        return v;
-}
-
-int parse_permille(const char *p) {
-        int v;
-
-        v = parse_permille_unbounded(p);
-        if (v > 1000)
-                return -ERANGE;
-
-        return v;
-}
-
-int parse_nice(const char *p, int *ret) {
-        int n, r;
-
-        r = safe_atoi(p, &n);
-        if (r < 0)
-                return r;
-
-        if (!nice_is_valid(n))
-                return -ERANGE;
-
-        *ret = n;
-        return 0;
-}
-
-int parse_ip_port(const char *s, uint16_t *ret) {
-        uint16_t l;
-        int r;
-
-        r = safe_atou16(s, &l);
-        if (r < 0)
-                return r;
-
-        if (l == 0)
-                return -EINVAL;
-
-        *ret = (uint16_t) l;
-
-        return 0;
-}
-
-int parse_dev(const char *s, dev_t *ret) {
-        unsigned x, y;
-        dev_t d;
-
-        if (sscanf(s, "%u:%u", &x, &y) != 2)
-                return -EINVAL;
-
-        d = makedev(x, y);
-        if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
-                return -EINVAL;
-
-        *ret = d;
-        return 0;
-}
-
-int parse_oom_score_adjust(const char *s, int *ret) {
-        int r, v;
-
-        assert(s);
-        assert(ret);
-
-        r = safe_atoi(s, &v);
-        if (r < 0)
-                return r;
-
-        if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)
-                return -ERANGE;
-
-        *ret = v;
-        return 0;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/parse-util.h b/src/systemd/src/basic/parse-util.h
deleted file mode 100644
index f3267f4c..00000000
--- a/src/systemd/src/basic/parse-util.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "macro.h"
-
-#define MODE_INVALID ((mode_t) -1)
-
-int parse_boolean(const char *v) _pure_;
-int parse_dev(const char *s, dev_t *ret);
-int parse_pid(const char *s, pid_t* ret_pid);
-int parse_mode(const char *s, mode_t *ret);
-int parse_ifindex(const char *s, int *ret);
-int parse_mtu(int family, const char *s, uint32_t *ret);
-
-int parse_size(const char *t, uint64_t base, uint64_t *size);
-int parse_range(const char *t, unsigned *lower, unsigned *upper);
-int parse_errno(const char *t);
-int parse_syscall_and_errno(const char *in, char **name, int *error);
-
-#define FORMAT_BYTES_MAX 8
-char *format_bytes(char *buf, size_t l, uint64_t t);
-
-int safe_atou_full(const char *s, unsigned base, unsigned *ret_u);
-
-static inline int safe_atou(const char *s, unsigned *ret_u) {
-        return safe_atou_full(s, 0, ret_u);
-}
-
-int safe_atoi(const char *s, int *ret_i);
-int safe_atollu(const char *s, unsigned long long *ret_u);
-int safe_atolli(const char *s, long long int *ret_i);
-
-int safe_atou8(const char *s, uint8_t *ret);
-
-int safe_atou16_full(const char *s, unsigned base, uint16_t *ret);
-
-static inline int safe_atou16(const char *s, uint16_t *ret) {
-        return safe_atou16_full(s, 0, ret);
-}
-
-static inline int safe_atoux16(const char *s, uint16_t *ret) {
-        return safe_atou16_full(s, 16, ret);
-}
-
-int safe_atoi16(const char *s, int16_t *ret);
-
-static inline int safe_atou32(const char *s, uint32_t *ret_u) {
-        assert_cc(sizeof(uint32_t) == sizeof(unsigned));
-        return safe_atou(s, (unsigned*) ret_u);
-}
-
-static inline int safe_atoi32(const char *s, int32_t *ret_i) {
-        assert_cc(sizeof(int32_t) == sizeof(int));
-        return safe_atoi(s, (int*) ret_i);
-}
-
-static inline int safe_atou64(const char *s, uint64_t *ret_u) {
-        assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
-        return safe_atollu(s, (unsigned long long*) ret_u);
-}
-
-static inline int safe_atoi64(const char *s, int64_t *ret_i) {
-        assert_cc(sizeof(int64_t) == sizeof(long long int));
-        return safe_atolli(s, (long long int*) ret_i);
-}
-
-#if LONG_MAX == INT_MAX
-static inline int safe_atolu(const char *s, unsigned long *ret_u) {
-        assert_cc(sizeof(unsigned long) == sizeof(unsigned));
-        return safe_atou(s, (unsigned*) ret_u);
-}
-static inline int safe_atoli(const char *s, long int *ret_u) {
-        assert_cc(sizeof(long int) == sizeof(int));
-        return safe_atoi(s, (int*) ret_u);
-}
-#else
-static inline int safe_atolu(const char *s, unsigned long *ret_u) {
-        assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
-        return safe_atollu(s, (unsigned long long*) ret_u);
-}
-static inline int safe_atoli(const char *s, long int *ret_u) {
-        assert_cc(sizeof(long int) == sizeof(long long int));
-        return safe_atolli(s, (long long int*) ret_u);
-}
-#endif
-
-#if SIZE_MAX == UINT_MAX
-static inline int safe_atozu(const char *s, size_t *ret_u) {
-        assert_cc(sizeof(size_t) == sizeof(unsigned));
-        return safe_atou(s, (unsigned *) ret_u);
-}
-#else
-static inline int safe_atozu(const char *s, size_t *ret_u) {
-        assert_cc(sizeof(size_t) == sizeof(long unsigned));
-        return safe_atolu(s, ret_u);
-}
-#endif
-
-int safe_atod(const char *s, double *ret_d);
-
-int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
-
-int parse_percent_unbounded(const char *p);
-int parse_percent(const char *p);
-
-int parse_permille_unbounded(const char *p);
-int parse_permille(const char *p);
-
-int parse_nice(const char *p, int *ret);
-
-int parse_ip_port(const char *s, uint16_t *ret);
-
-int parse_oom_score_adjust(const char *s, int *ret);
diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c
deleted file mode 100644
index 3656a011..00000000
--- a/src/systemd/src/basic/path-util.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the
- * POSIX version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
-#include "alloc-util.h"
-#include "extract-word.h"
-#include "fs-util.h"
-#include "glob-util.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "stat-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-#include "utf8.h"
-
-bool path_is_absolute(const char *p) {
-        return p[0] == '/';
-}
-
-#if 0 /* NM_IGNORED */
-bool is_path(const char *p) {
-        return !!strchr(p, '/');
-}
-
-int path_split_and_make_absolute(const char *p, char ***ret) {
-        char **l;
-        int r;
-
-        assert(p);
-        assert(ret);
-
-        l = strv_split(p, ":");
-        if (!l)
-                return -ENOMEM;
-
-        r = path_strv_make_absolute_cwd(l);
-        if (r < 0) {
-                strv_free(l);
-                return r;
-        }
-
-        *ret = l;
-        return r;
-}
-
-char *path_make_absolute(const char *p, const char *prefix) {
-        assert(p);
-
-        /* Makes every item in the list an absolute path by prepending
-         * the prefix, if specified and necessary */
-
-        if (path_is_absolute(p) || isempty(prefix))
-                return strdup(p);
-
-        if (endswith(prefix, "/"))
-                return strjoin(prefix, p);
-        else
-                return strjoin(prefix, "/", p);
-}
-
-int safe_getcwd(char **ret) {
-        char *cwd;
-
-        cwd = get_current_dir_name();
-        if (!cwd)
-                return negative_errno();
-
-        /* Let's make sure the directory is really absolute, to protect us from the logic behind
-         * CVE-2018-1000001 */
-        if (cwd[0] != '/') {
-                free(cwd);
-                return -ENOMEDIUM;
-        }
-
-        *ret = cwd;
-        return 0;
-}
-
-int path_make_absolute_cwd(const char *p, char **ret) {
-        char *c;
-        int r;
-
-        assert(p);
-        assert(ret);
-
-        /* Similar to path_make_absolute(), but prefixes with the
-         * current working directory. */
-
-        if (path_is_absolute(p))
-                c = strdup(p);
-        else {
-                _cleanup_free_ char *cwd = NULL;
-
-                r = safe_getcwd(&cwd);
-                if (r < 0)
-                        return r;
-
-                c = path_join(NULL, cwd, p);
-        }
-        if (!c)
-                return -ENOMEM;
-
-        *ret = c;
-        return 0;
-}
-
-int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
-        char *f, *t, *r, *p;
-        unsigned n_parents = 0;
-
-        assert(from_dir);
-        assert(to_path);
-        assert(_r);
-
-        /* Strips the common part, and adds ".." elements as necessary. */
-
-        if (!path_is_absolute(from_dir) || !path_is_absolute(to_path))
-                return -EINVAL;
-
-        f = strdupa(from_dir);
-        t = strdupa(to_path);
-
-        path_simplify(f, true);
-        path_simplify(t, true);
-
-        /* Skip the common part. */
-        for (;;) {
-                size_t a, b;
-
-                f += *f == '/';
-                t += *t == '/';
-
-                if (!*f) {
-                        if (!*t)
-                                /* from_dir equals to_path. */
-                                r = strdup(".");
-                        else
-                                /* from_dir is a parent directory of to_path. */
-                                r = strdup(t);
-                        if (!r)
-                                return -ENOMEM;
-
-                        *_r = r;
-                        return 0;
-                }
-
-                if (!*t)
-                        break;
-
-                a = strcspn(f, "/");
-                b = strcspn(t, "/");
-
-                if (a != b || memcmp(f, t, a) != 0)
-                        break;
-
-                f += a;
-                t += b;
-        }
-
-        /* If we're here, then "from_dir" has one or more elements that need to
-         * be replaced with "..". */
-
-        /* Count the number of necessary ".." elements. */
-        for (; *f;) {
-                size_t w;
-
-                w = strcspn(f, "/");
-
-                /* If this includes ".." we can't do a simple series of "..", refuse */
-                if (w == 2 && f[0] == '.' && f[1] == '.')
-                        return -EINVAL;
-
-                /* Count number of elements */
-                n_parents++;
-
-                f += w;
-                f += *f == '/';
-        }
-
-        r = new(char, n_parents * 3 + strlen(t) + 1);
-        if (!r)
-                return -ENOMEM;
-
-        for (p = r; n_parents > 0; n_parents--)
-                p = mempcpy(p, "../", 3);
-
-        if (*t)
-                strcpy(p, t);
-        else
-                /* Remove trailing slash */
-                *(--p) = 0;
-
-        *_r = r;
-        return 0;
-}
-
-int path_strv_make_absolute_cwd(char **l) {
-        char **s;
-        int r;
-
-        /* Goes through every item in the string list and makes it
-         * absolute. This works in place and won't rollback any
-         * changes on failure. */
-
-        STRV_FOREACH(s, l) {
-                char *t;
-
-                r = path_make_absolute_cwd(*s, &t);
-                if (r < 0)
-                        return r;
-
-                path_simplify(t, false);
-                free_and_replace(*s, t);
-        }
-
-        return 0;
-}
-
-char **path_strv_resolve(char **l, const char *root) {
-        char **s;
-        unsigned k = 0;
-        bool enomem = false;
-        int r;
-
-        if (strv_isempty(l))
-                return l;
-
-        /* Goes through every item in the string list and canonicalize
-         * the path. This works in place and won't rollback any
-         * changes on failure. */
-
-        STRV_FOREACH(s, l) {
-                _cleanup_free_ char *orig = NULL;
-                char *t, *u;
-
-                if (!path_is_absolute(*s)) {
-                        free(*s);
-                        continue;
-                }
-
-                if (root) {
-                        orig = *s;
-                        t = prefix_root(root, orig);
-                        if (!t) {
-                                enomem = true;
-                                continue;
-                        }
-                } else
-                        t = *s;
-
-                r = chase_symlinks(t, root, 0, &u);
-                if (r == -ENOENT) {
-                        if (root) {
-                                u = TAKE_PTR(orig);
-                                free(t);
-                        } else
-                                u = t;
-                } else if (r < 0) {
-                        free(t);
-
-                        if (r == -ENOMEM)
-                                enomem = true;
-
-                        continue;
-                } else if (root) {
-                        char *x;
-
-                        free(t);
-                        x = path_startswith(u, root);
-                        if (x) {
-                                /* restore the slash if it was lost */
-                                if (!startswith(x, "/"))
-                                        *(--x) = '/';
-
-                                t = strdup(x);
-                                free(u);
-                                if (!t) {
-                                        enomem = true;
-                                        continue;
-                                }
-                                u = t;
-                        } else {
-                                /* canonicalized path goes outside of
-                                 * prefix, keep the original path instead */
-                                free_and_replace(u, orig);
-                        }
-                } else
-                        free(t);
-
-                l[k++] = u;
-        }
-
-        l[k] = NULL;
-
-        if (enomem)
-                return NULL;
-
-        return l;
-}
-
-char **path_strv_resolve_uniq(char **l, const char *root) {
-
-        if (strv_isempty(l))
-                return l;
-
-        if (!path_strv_resolve(l, root))
-                return NULL;
-
-        return strv_uniq(l);
-}
-#endif /* NM_IGNORED */
-
-char *path_simplify(char *path, bool kill_dots) {
-        char *f, *t;
-        bool slash = false, ignore_slash = false, absolute;
-
-        assert(path);
-
-        /* Removes redundant inner and trailing slashes. Also removes unnecessary dots
-         * if kill_dots is true. Modifies the passed string in-place.
-         *
-         * ///foo//./bar/.   becomes /foo/./bar/.  (if kill_dots is false)
-         * ///foo//./bar/.   becomes /foo/bar      (if kill_dots is true)
-         * .//./foo//./bar/. becomes ./foo/bar     (if kill_dots is false)
-         * .//./foo//./bar/. becomes foo/bar       (if kill_dots is true)
-         */
-
-        absolute = path_is_absolute(path);
-
-        f = path;
-        if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/')) {
-                ignore_slash = true;
-                f++;
-        }
-
-        for (t = path; *f; f++) {
-
-                if (*f == '/') {
-                        slash = true;
-                        continue;
-                }
-
-                if (slash) {
-                        if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/'))
-                                continue;
-
-                        slash = false;
-                        if (ignore_slash)
-                                ignore_slash = false;
-                        else
-                                *(t++) = '/';
-                }
-
-                *(t++) = *f;
-        }
-
-        /* Special rule, if we are talking of the root directory, a trailing slash is good */
-        if (absolute && t == path)
-                *(t++) = '/';
-
-        *t = 0;
-        return path;
-}
-
-char* path_startswith(const char *path, const char *prefix) {
-        assert(path);
-        assert(prefix);
-
-        /* Returns a pointer to the start of the first component after the parts matched by
-         * the prefix, iff
-         * - both paths are absolute or both paths are relative,
-         * and
-         * - each component in prefix in turn matches a component in path at the same position.
-         * An empty string will be returned when the prefix and path are equivalent.
-         *
-         * Returns NULL otherwise.
-         */
-
-        if ((path[0] == '/') != (prefix[0] == '/'))
-                return NULL;
-
-        for (;;) {
-                size_t a, b;
-
-                path += strspn(path, "/");
-                prefix += strspn(prefix, "/");
-
-                if (*prefix == 0)
-                        return (char*) path;
-
-                if (*path == 0)
-                        return NULL;
-
-                a = strcspn(path, "/");
-                b = strcspn(prefix, "/");
-
-                if (a != b)
-                        return NULL;
-
-                if (memcmp(path, prefix, a) != 0)
-                        return NULL;
-
-                path += a;
-                prefix += b;
-        }
-}
-
-int path_compare(const char *a, const char *b) {
-        int d;
-
-        assert(a);
-        assert(b);
-
-        /* A relative path and an abolute path must not compare as equal.
-         * Which one is sorted before the other does not really matter.
-         * Here a relative path is ordered before an absolute path. */
-        d = (a[0] == '/') - (b[0] == '/');
-        if (d != 0)
-                return d;
-
-        for (;;) {
-                size_t j, k;
-
-                a += strspn(a, "/");
-                b += strspn(b, "/");
-
-                if (*a == 0 && *b == 0)
-                        return 0;
-
-                /* Order prefixes first: "/foo" before "/foo/bar" */
-                if (*a == 0)
-                        return -1;
-                if (*b == 0)
-                        return 1;
-
-                j = strcspn(a, "/");
-                k = strcspn(b, "/");
-
-                /* Alphabetical sort: "/foo/aaa" before "/foo/b" */
-                d = memcmp(a, b, MIN(j, k));
-                if (d != 0)
-                        return (d > 0) - (d < 0); /* sign of d */
-
-                /* Sort "/foo/a" before "/foo/aaa" */
-                d = (j > k) - (j < k);  /* sign of (j - k) */
-                if (d != 0)
-                        return d;
-
-                a += j;
-                b += k;
-        }
-}
-
-bool path_equal(const char *a, const char *b) {
-        return path_compare(a, b) == 0;
-}
-
-#if 0 /* NM_IGNORED */
-bool path_equal_or_files_same(const char *a, const char *b, int flags) {
-        return path_equal(a, b) || files_same(a, b, flags) > 0;
-}
-
-char* path_join(const char *root, const char *path, const char *rest) {
-        assert(path);
-
-        if (!isempty(root))
-                return strjoin(root, endswith(root, "/") ? "" : "/",
-                               path[0] == '/' ? path+1 : path,
-                               rest ? (endswith(path, "/") ? "" : "/") : NULL,
-                               rest && rest[0] == '/' ? rest+1 : rest);
-        else
-                return strjoin(path,
-                               rest ? (endswith(path, "/") ? "" : "/") : NULL,
-                               rest && rest[0] == '/' ? rest+1 : rest);
-}
-
-int find_binary(const char *name, char **ret) {
-        int last_error, r;
-        const char *p;
-
-        assert(name);
-
-        if (is_path(name)) {
-                if (access(name, X_OK) < 0)
-                        return -errno;
-
-                if (ret) {
-                        r = path_make_absolute_cwd(name, ret);
-                        if (r < 0)
-                                return r;
-                }
-
-                return 0;
-        }
-
-        /**
-         * Plain getenv, not secure_getenv, because we want
-         * to actually allow the user to pick the binary.
-         */
-        p = getenv("PATH");
-        if (!p)
-                p = DEFAULT_PATH;
-
-        last_error = -ENOENT;
-
-        for (;;) {
-                _cleanup_free_ char *j = NULL, *element = NULL;
-
-                r = extract_first_word(&p, &element, ":", EXTRACT_RELAX|EXTRACT_DONT_COALESCE_SEPARATORS);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        break;
-
-                if (!path_is_absolute(element))
-                        continue;
-
-                j = strjoin(element, "/", name);
-                if (!j)
-                        return -ENOMEM;
-
-                if (access(j, X_OK) >= 0) {
-                        /* Found it! */
-
-                        if (ret) {
-                                *ret = path_simplify(j, false);
-                                j = NULL;
-                        }
-
-                        return 0;
-                }
-
-                last_error = -errno;
-        }
-
-        return last_error;
-}
-
-bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool update) {
-        bool changed = false;
-        const char* const* i;
-
-        assert(timestamp);
-
-        if (!paths)
-                return false;
-
-        STRV_FOREACH(i, paths) {
-                struct stat stats;
-                usec_t u;
-
-                if (stat(*i, &stats) < 0)
-                        continue;
-
-                u = timespec_load(&stats.st_mtim);
-
-                /* first check */
-                if (*timestamp >= u)
-                        continue;
-
-                log_debug("timestamp of '%s' changed", *i);
-
-                /* update timestamp */
-                if (update) {
-                        *timestamp = u;
-                        changed = true;
-                } else
-                        return true;
-        }
-
-        return changed;
-}
-
-static int binary_is_good(const char *binary) {
-        _cleanup_free_ char *p = NULL, *d = NULL;
-        int r;
-
-        r = find_binary(binary, &p);
-        if (r == -ENOENT)
-                return 0;
-        if (r < 0)
-                return r;
-
-        /* An fsck that is linked to /bin/true is a non-existent
-         * fsck */
-
-        r = readlink_malloc(p, &d);
-        if (r == -EINVAL) /* not a symlink */
-                return 1;
-        if (r < 0)
-                return r;
-
-        return !PATH_IN_SET(d, "true"
-                               "/bin/true",
-                               "/usr/bin/true",
-                               "/dev/null");
-}
-
-int fsck_exists(const char *fstype) {
-        const char *checker;
-
-        assert(fstype);
-
-        if (streq(fstype, "auto"))
-                return -EINVAL;
-
-        checker = strjoina("fsck.", fstype);
-        return binary_is_good(checker);
-}
-
-int mkfs_exists(const char *fstype) {
-        const char *mkfs;
-
-        assert(fstype);
-
-        if (streq(fstype, "auto"))
-                return -EINVAL;
-
-        mkfs = strjoina("mkfs.", fstype);
-        return binary_is_good(mkfs);
-}
-
-char *prefix_root(const char *root, const char *path) {
-        char *n, *p;
-        size_t l;
-
-        /* If root is passed, prefixes path with it. Otherwise returns
-         * it as is. */
-
-        assert(path);
-
-        /* First, drop duplicate prefixing slashes from the path */
-        while (path[0] == '/' && path[1] == '/')
-                path++;
-
-        if (empty_or_root(root))
-                return strdup(path);
-
-        l = strlen(root) + 1 + strlen(path) + 1;
-
-        n = new(char, l);
-        if (!n)
-                return NULL;
-
-        p = stpcpy(n, root);
-
-        while (p > n && p[-1] == '/')
-                p--;
-
-        if (path[0] != '/')
-                *(p++) = '/';
-
-        strcpy(p, path);
-        return n;
-}
-
-int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) {
-        char *p;
-        int r;
-
-        /*
-         * This function is intended to be used in command line
-         * parsers, to handle paths that are passed in. It makes the
-         * path absolute, and reduces it to NULL if omitted or
-         * root (the latter optionally).
-         *
-         * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON
-         * SUCCESS! Hence, do not pass in uninitialized pointers.
-         */
-
-        if (isempty(path)) {
-                *arg = mfree(*arg);
-                return 0;
-        }
-
-        r = path_make_absolute_cwd(path, &p);
-        if (r < 0)
-                return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
-
-        path_simplify(p, false);
-        if (suppress_root && empty_or_root(p))
-                p = mfree(p);
-
-        free_and_replace(*arg, p);
-
-        return 0;
-}
-
-char* dirname_malloc(const char *path) {
-        char *d, *dir, *dir2;
-
-        assert(path);
-
-        d = strdup(path);
-        if (!d)
-                return NULL;
-
-        dir = dirname(d);
-        assert(dir);
-
-        if (dir == d)
-                return d;
-
-        dir2 = strdup(dir);
-        free(d);
-
-        return dir2;
-}
-
-const char *last_path_component(const char *path) {
-
-        /* Finds the last component of the path, preserving the optional trailing slash that signifies a directory.
-         *
-         *    a/b/c → c
-         *    a/b/c/ → c/
-         *    x → x
-         *    x/ → x/
-         *    /y → y
-         *    /y/ → y/
-         *    / → /
-         *    // → /
-         *    /foo/a → a
-         *    /foo/a/ → a/
-         *
-         *    Also, the empty string is mapped to itself.
-         *
-         * This is different than basename(), which returns "" when a trailing slash is present.
-         */
-
-        unsigned l, k;
-
-        l = k = strlen(path);
-        if (l == 0) /* special case — an empty string */
-                return path;
-
-        while (k > 0 && path[k-1] == '/')
-                k--;
-
-        if (k == 0) /* the root directory */
-                return path + l - 1;
-
-        while (k > 0 && path[k-1] != '/')
-                k--;
-
-        return path + k;
-}
-#endif /* NM_IGNORED */
-
-bool filename_is_valid(const char *p) {
-        const char *e;
-
-        if (isempty(p))
-                return false;
-
-        if (dot_or_dot_dot(p))
-                return false;
-
-        e = strchrnul(p, '/');
-        if (*e != 0)
-                return false;
-
-        if (e - p > FILENAME_MAX)
-                return false;
-
-        return true;
-}
-
-bool path_is_normalized(const char *p) {
-
-        if (isempty(p))
-                return false;
-
-        if (dot_or_dot_dot(p))
-                return false;
-
-        if (startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
-                return false;
-
-        if (strlen(p)+1 > PATH_MAX)
-                return false;
-
-        if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
-                return false;
-
-        if (strstr(p, "//"))
-                return false;
-
-        return true;
-}
-
-#if 0 /* NM_IGNORED */
-char *file_in_same_dir(const char *path, const char *filename) {
-        char *e, *ret;
-        size_t k;
-
-        assert(path);
-        assert(filename);
-
-        /* This removes the last component of path and appends
-         * filename, unless the latter is absolute anyway or the
-         * former isn't */
-
-        if (path_is_absolute(filename))
-                return strdup(filename);
-
-        e = strrchr(path, '/');
-        if (!e)
-                return strdup(filename);
-
-        k = strlen(filename);
-        ret = new(char, (e + 1 - path) + k + 1);
-        if (!ret)
-                return NULL;
-
-        memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
-        return ret;
-}
-
-bool hidden_or_backup_file(const char *filename) {
-        const char *p;
-
-        assert(filename);
-
-        if (filename[0] == '.' ||
-            streq(filename, "lost+found") ||
-            streq(filename, "aquota.user") ||
-            streq(filename, "aquota.group") ||
-            endswith(filename, "~"))
-                return true;
-
-        p = strrchr(filename, '.');
-        if (!p)
-                return false;
-
-        /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
-         * with always new suffixes and that everybody else should just adjust to that, then it really should be on
-         * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
-         * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
-         * string. Specifically: there's now:
-         *
-         *    The generic suffixes "~" and ".bak" for backup files
-         *    The generic prefix "." for hidden files
-         *
-         * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
-         * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
-         */
-
-        return STR_IN_SET(p + 1,
-                          "rpmnew",
-                          "rpmsave",
-                          "rpmorig",
-                          "dpkg-old",
-                          "dpkg-new",
-                          "dpkg-tmp",
-                          "dpkg-dist",
-                          "dpkg-bak",
-                          "dpkg-backup",
-                          "dpkg-remove",
-                          "ucf-new",
-                          "ucf-old",
-                          "ucf-dist",
-                          "swp",
-                          "bak",
-                          "old",
-                          "new");
-}
-
-bool is_device_path(const char *path) {
-
-        /* Returns true on paths that likely refer to a device, either by path in sysfs or to something in /dev */
-
-        return PATH_STARTSWITH_SET(path, "/dev/", "/sys/");
-}
-
-bool valid_device_node_path(const char *path) {
-
-        /* Some superficial checks whether the specified path is a valid device node path, all without looking at the
-         * actual device node. */
-
-        if (!PATH_STARTSWITH_SET(path, "/dev/", "/run/systemd/inaccessible/"))
-                return false;
-
-        if (endswith(path, "/")) /* can't be a device node if it ends in a slash */
-                return false;
-
-        return path_is_normalized(path);
-}
-
-bool valid_device_allow_pattern(const char *path) {
-        assert(path);
-
-        /* Like valid_device_node_path(), but also allows full-subsystem expressions, like DeviceAllow= and DeviceDeny=
-         * accept it */
-
-        if (startswith(path, "block-") ||
-            startswith(path, "char-"))
-                return true;
-
-        return valid_device_node_path(path);
-}
-
-int systemd_installation_has_version(const char *root, unsigned minimal_version) {
-        const char *pattern;
-        int r;
-
-        /* Try to guess if systemd installation is later than the specified version. This
-         * is hacky and likely to yield false negatives, particularly if the installation
-         * is non-standard. False positives should be relatively rare.
-         */
-
-        NULSTR_FOREACH(pattern,
-                       /* /lib works for systems without usr-merge, and for systems with a sane
-                        * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary
-                        * for Gentoo which does a merge without making /lib a symlink.
-                        */
-                       "lib/systemd/libsystemd-shared-*.so\0"
-                       "lib64/systemd/libsystemd-shared-*.so\0"
-                       "usr/lib/systemd/libsystemd-shared-*.so\0"
-                       "usr/lib64/systemd/libsystemd-shared-*.so\0") {
-
-                _cleanup_strv_free_ char **names = NULL;
-                _cleanup_free_ char *path = NULL;
-                char *c, **name;
-
-                path = prefix_root(root, pattern);
-                if (!path)
-                        return -ENOMEM;
-
-                r = glob_extend(&names, path);
-                if (r == -ENOENT)
-                        continue;
-                if (r < 0)
-                        return r;
-
-                assert_se(c = endswith(path, "*.so"));
-                *c = '\0'; /* truncate the glob part */
-
-                STRV_FOREACH(name, names) {
-                        /* This is most likely to run only once, hence let's not optimize anything. */
-                        char *t, *t2;
-                        unsigned version;
-
-                        t = startswith(*name, path);
-                        if (!t)
-                                continue;
-
-                        t2 = endswith(t, ".so");
-                        if (!t2)
-                                continue;
-
-                        t2[0] = '\0'; /* truncate the suffix */
-
-                        r = safe_atou(t, &version);
-                        if (r < 0) {
-                                log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name);
-                                continue;
-                        }
-
-                        log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).",
-                                  *name, version,
-                                  version >= minimal_version ? "OK" : "too old");
-                        if (version >= minimal_version)
-                                return true;
-                }
-        }
-
-        return false;
-}
-#endif /* NM_IGNORED */
-
-bool dot_or_dot_dot(const char *path) {
-        if (!path)
-                return false;
-        if (path[0] != '.')
-                return false;
-        if (path[1] == 0)
-                return true;
-        if (path[1] != '.')
-                return false;
-
-        return path[2] == 0;
-}
-
-#if 0 /* NM_IGNORED */
-bool empty_or_root(const char *root) {
-
-        /* For operations relative to some root directory, returns true if the specified root directory is redundant,
-         * i.e. either / or NULL or the empty string or any equivalent. */
-
-        if (!root)
-                return true;
-
-        return root[strspn(root, "/")] == 0;
-}
-
-int path_simplify_and_warn(
-                char *path,
-                unsigned flag,
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *lvalue) {
-
-        bool absolute, fatal = flag & PATH_CHECK_FATAL;
-
-        assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
-
-        if (!utf8_is_valid(path)) {
-                log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
-                return -EINVAL;
-        }
-
-        if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
-                absolute = path_is_absolute(path);
-
-                if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "%s= path is not absolute%s: %s",
-                                   lvalue, fatal ? "" : ", ignoring", path);
-                        return -EINVAL;
-                }
-
-                if (absolute && (flag & PATH_CHECK_RELATIVE)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "%s= path is absolute%s: %s",
-                                   lvalue, fatal ? "" : ", ignoring", path);
-                        return -EINVAL;
-                }
-        }
-
-        path_simplify(path, true);
-
-        if (!path_is_normalized(path)) {
-                log_syntax(unit, LOG_ERR, filename, line, 0,
-                           "%s= path is not normalized%s: %s",
-                           lvalue, fatal ? "" : ", ignoring", path);
-                return -EINVAL;
-        }
-
-        return 0;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/path-util.h b/src/systemd/src/basic/path-util.h
deleted file mode 100644
index 72f3ce36..00000000
--- a/src/systemd/src/basic/path-util.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <alloca.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#include "macro.h"
-#include "string-util.h"
-#include "time-util.h"
-
-#if 0 /* NM_IGNORED */
-#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
-#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
-
-#define PATH_NORMAL_SBIN_BIN(x) x "bin"
-#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
-
-#if HAVE_SPLIT_BIN
-#  define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
-#  define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
-#else
-#  define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
-#  define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
-#endif
-
-#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
-#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
-#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
-#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/")
-#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
-
-#if HAVE_SPLIT_USR
-#  define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
-#  define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR
-#else
-#  define DEFAULT_PATH DEFAULT_PATH_NORMAL
-#  define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR
-#endif
-#endif /* NM_IGNORED */
-
-bool is_path(const char *p) _pure_;
-int path_split_and_make_absolute(const char *p, char ***ret);
-bool path_is_absolute(const char *p) _pure_;
-char* path_make_absolute(const char *p, const char *prefix);
-int safe_getcwd(char **ret);
-int path_make_absolute_cwd(const char *p, char **ret);
-int path_make_relative(const char *from_dir, const char *to_path, char **_r);
-char* path_startswith(const char *path, const char *prefix) _pure_;
-int path_compare(const char *a, const char *b) _pure_;
-bool path_equal(const char *a, const char *b) _pure_;
-bool path_equal_or_files_same(const char *a, const char *b, int flags);
-char* path_join(const char *root, const char *path, const char *rest);
-char* path_simplify(char *path, bool kill_dots);
-
-static inline bool path_equal_ptr(const char *a, const char *b) {
-        return !!a == !!b && (!a || path_equal(a, b));
-}
-
-/* Note: the search terminates on the first NULL item. */
-#define PATH_IN_SET(p, ...)                                     \
-        ({                                                      \
-                char **_s;                                      \
-                bool _found = false;                            \
-                STRV_FOREACH(_s, STRV_MAKE(__VA_ARGS__))        \
-                        if (path_equal(p, *_s)) {               \
-                               _found = true;                   \
-                               break;                           \
-                        }                                       \
-                _found;                                         \
-        })
-
-#define PATH_STARTSWITH_SET(p, ...)                             \
-        ({                                                      \
-                char **s;                                       \
-                bool _found = false;                            \
-                STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__))         \
-                        if (path_startswith(p, *s)) {           \
-                               _found = true;                   \
-                               break;                           \
-                        }                                       \
-                _found;                                         \
-        })
-
-int path_strv_make_absolute_cwd(char **l);
-char** path_strv_resolve(char **l, const char *root);
-char** path_strv_resolve_uniq(char **l, const char *root);
-
-int find_binary(const char *name, char **filename);
-
-bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
-
-int fsck_exists(const char *fstype);
-int mkfs_exists(const char *fstype);
-
-/* Iterates through the path prefixes of the specified path, going up
- * the tree, to root. Also returns "" (and not "/"!) for the root
- * directory. Excludes the specified directory itself */
-#define PATH_FOREACH_PREFIX(prefix, path) \
-        for (char *_slash = ({ path_simplify(strcpy(prefix, path), false); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
-
-/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */
-#define PATH_FOREACH_PREFIX_MORE(prefix, path) \
-        for (char *_slash = ({ path_simplify(strcpy(prefix, path), false); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
-
-char *prefix_root(const char *root, const char *path);
-
-/* Similar to prefix_root(), but returns an alloca() buffer, or
- * possibly a const pointer into the path parameter */
-#define prefix_roota(root, path)                                        \
-        ({                                                              \
-                const char* _path = (path), *_root = (root), *_ret;     \
-                char *_p, *_n;                                          \
-                size_t _l;                                              \
-                while (_path[0] == '/' && _path[1] == '/')              \
-                        _path ++;                                       \
-                if (empty_or_root(_root))                               \
-                        _ret = _path;                                   \
-                else {                                                  \
-                        _l = strlen(_root) + 1 + strlen(_path) + 1;     \
-                        _n = alloca(_l);                                \
-                        _p = stpcpy(_n, _root);                         \
-                        while (_p > _n && _p[-1] == '/')                \
-                                _p--;                                   \
-                        if (_path[0] != '/')                            \
-                                *(_p++) = '/';                          \
-                        strcpy(_p, _path);                              \
-                        _ret = _n;                                      \
-                }                                                       \
-                _ret;                                                   \
-        })
-
-int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg);
-
-char* dirname_malloc(const char *path);
-const char *last_path_component(const char *path);
-
-bool filename_is_valid(const char *p) _pure_;
-bool path_is_normalized(const char *p) _pure_;
-
-char *file_in_same_dir(const char *path, const char *filename);
-
-bool hidden_or_backup_file(const char *filename) _pure_;
-
-bool is_device_path(const char *path);
-
-bool valid_device_node_path(const char *path);
-bool valid_device_allow_pattern(const char *path);
-
-int systemd_installation_has_version(const char *root, unsigned minimal_version);
-
-bool dot_or_dot_dot(const char *path);
-
-static inline const char *skip_dev_prefix(const char *p) {
-        const char *e;
-
-        /* Drop any /dev prefix if there is any */
-
-        e = path_startswith(p, "/dev/");
-
-        return e ?: p;
-}
-
-bool empty_or_root(const char *root);
-static inline const char *empty_to_root(const char *path) {
-        return isempty(path) ? "/" : path;
-}
-
-enum {
-        PATH_CHECK_FATAL    = 1 << 0,  /* If not set, then error message is appended with 'ignoring'. */
-        PATH_CHECK_ABSOLUTE = 1 << 1,
-        PATH_CHECK_RELATIVE = 1 << 2,
-};
-
-int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue);
diff --git a/src/systemd/src/basic/prioq.c b/src/systemd/src/basic/prioq.c
deleted file mode 100644
index 79900df3..00000000
--- a/src/systemd/src/basic/prioq.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-/*
- * Priority Queue
- * The prioq object implements a priority queue. That is, it orders objects by
- * their priority and allows O(1) access to the object with the highest
- * priority. Insertion and removal are Θ(log n). Optionally, the caller can
- * provide a pointer to an index which will be kept up-to-date by the prioq.
- *
- * The underlying algorithm used in this implementation is a Heap.
- */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include "alloc-util.h"
-#include "hashmap.h"
-#include "prioq.h"
-
-struct prioq_item {
-        void *data;
-        unsigned *idx;
-};
-
-struct Prioq {
-        compare_func_t compare_func;
-        unsigned n_items, n_allocated;
-
-        struct prioq_item *items;
-};
-
-Prioq *prioq_new(compare_func_t compare_func) {
-        Prioq *q;
-
-        q = new0(Prioq, 1);
-        if (!q)
-                return q;
-
-        q->compare_func = compare_func;
-        return q;
-}
-
-Prioq* prioq_free(Prioq *q) {
-        if (!q)
-                return NULL;
-
-        free(q->items);
-        return mfree(q);
-}
-
-int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) {
-        assert(q);
-
-        if (*q)
-                return 0;
-
-        *q = prioq_new(compare_func);
-        if (!*q)
-                return -ENOMEM;
-
-        return 0;
-}
-
-static void swap(Prioq *q, unsigned j, unsigned k) {
-        void *saved_data;
-        unsigned *saved_idx;
-
-        assert(q);
-        assert(j < q->n_items);
-        assert(k < q->n_items);
-
-        assert(!q->items[j].idx || *(q->items[j].idx) == j);
-        assert(!q->items[k].idx || *(q->items[k].idx) == k);
-
-        saved_data = q->items[j].data;
-        saved_idx = q->items[j].idx;
-        q->items[j].data = q->items[k].data;
-        q->items[j].idx = q->items[k].idx;
-        q->items[k].data = saved_data;
-        q->items[k].idx = saved_idx;
-
-        if (q->items[j].idx)
-                *q->items[j].idx = j;
-
-        if (q->items[k].idx)
-                *q->items[k].idx = k;
-}
-
-static unsigned shuffle_up(Prioq *q, unsigned idx) {
-        assert(q);
-
-        while (idx > 0) {
-                unsigned k;
-
-                k = (idx-1)/2;
-
-                if (q->compare_func(q->items[k].data, q->items[idx].data) <= 0)
-                        break;
-
-                swap(q, idx, k);
-                idx = k;
-        }
-
-        return idx;
-}
-
-static unsigned shuffle_down(Prioq *q, unsigned idx) {
-        assert(q);
-
-        for (;;) {
-                unsigned j, k, s;
-
-                k = (idx+1)*2; /* right child */
-                j = k-1;       /* left child */
-
-                if (j >= q->n_items)
-                        break;
-
-                if (q->compare_func(q->items[j].data, q->items[idx].data) < 0)
-
-                        /* So our left child is smaller than we are, let's
-                         * remember this fact */
-                        s = j;
-                else
-                        s = idx;
-
-                if (k < q->n_items &&
-                    q->compare_func(q->items[k].data, q->items[s].data) < 0)
-
-                        /* So our right child is smaller than we are, let's
-                         * remember this fact */
-                        s = k;
-
-                /* s now points to the smallest of the three items */
-
-                if (s == idx)
-                        /* No swap necessary, we're done */
-                        break;
-
-                swap(q, idx, s);
-                idx = s;
-        }
-
-        return idx;
-}
-
-int prioq_put(Prioq *q, void *data, unsigned *idx) {
-        struct prioq_item *i;
-        unsigned k;
-
-        assert(q);
-
-        if (q->n_items >= q->n_allocated) {
-                unsigned n;
-                struct prioq_item *j;
-
-                n = MAX((q->n_items+1) * 2, 16u);
-                j = reallocarray(q->items, n, sizeof(struct prioq_item));
-                if (!j)
-                        return -ENOMEM;
-
-                q->items = j;
-                q->n_allocated = n;
-        }
-
-        k = q->n_items++;
-        i = q->items + k;
-        i->data = data;
-        i->idx = idx;
-
-        if (idx)
-                *idx = k;
-
-        shuffle_up(q, k);
-
-        return 0;
-}
-
-static void remove_item(Prioq *q, struct prioq_item *i) {
-        struct prioq_item *l;
-
-        assert(q);
-        assert(i);
-
-        l = q->items + q->n_items - 1;
-
-        if (i == l)
-                /* Last entry, let's just remove it */
-                q->n_items--;
-        else {
-                unsigned k;
-
-                /* Not last entry, let's replace the last entry with
-                 * this one, and reshuffle */
-
-                k = i - q->items;
-
-                i->data = l->data;
-                i->idx = l->idx;
-                if (i->idx)
-                        *i->idx = k;
-                q->n_items--;
-
-                k = shuffle_down(q, k);
-                shuffle_up(q, k);
-        }
-}
-
-_pure_ static struct prioq_item* find_item(Prioq *q, void *data, unsigned *idx) {
-        struct prioq_item *i;
-
-        assert(q);
-
-        if (idx) {
-                if (*idx == PRIOQ_IDX_NULL ||
-                    *idx > q->n_items)
-                        return NULL;
-
-                i = q->items + *idx;
-                if (i->data != data)
-                        return NULL;
-
-                return i;
-        } else {
-                for (i = q->items; i < q->items + q->n_items; i++)
-                        if (i->data == data)
-                                return i;
-                return NULL;
-        }
-}
-
-int prioq_remove(Prioq *q, void *data, unsigned *idx) {
-        struct prioq_item *i;
-
-        if (!q)
-                return 0;
-
-        i = find_item(q, data, idx);
-        if (!i)
-                return 0;
-
-        remove_item(q, i);
-        return 1;
-}
-
-int prioq_reshuffle(Prioq *q, void *data, unsigned *idx) {
-        struct prioq_item *i;
-        unsigned k;
-
-        assert(q);
-
-        i = find_item(q, data, idx);
-        if (!i)
-                return 0;
-
-        k = i - q->items;
-        k = shuffle_down(q, k);
-        shuffle_up(q, k);
-        return 1;
-}
-
-void *prioq_peek(Prioq *q) {
-
-        if (!q)
-                return NULL;
-
-        if (q->n_items <= 0)
-                return NULL;
-
-        return q->items[0].data;
-}
-
-void *prioq_pop(Prioq *q) {
-        void *data;
-
-        if (!q)
-                return NULL;
-
-        if (q->n_items <= 0)
-                return NULL;
-
-        data = q->items[0].data;
-        remove_item(q, q->items);
-        return data;
-}
-
-unsigned prioq_size(Prioq *q) {
-
-        if (!q)
-                return 0;
-
-        return q->n_items;
-}
-
-bool prioq_isempty(Prioq *q) {
-
-        if (!q)
-                return true;
-
-        return q->n_items <= 0;
-}
diff --git a/src/systemd/src/basic/prioq.h b/src/systemd/src/basic/prioq.h
deleted file mode 100644
index e0361752..00000000
--- a/src/systemd/src/basic/prioq.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-
-#include "hashmap.h"
-#include "macro.h"
-
-typedef struct Prioq Prioq;
-
-#define PRIOQ_IDX_NULL ((unsigned) -1)
-
-Prioq *prioq_new(compare_func_t compare);
-Prioq *prioq_free(Prioq *q);
-int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func);
-
-int prioq_put(Prioq *q, void *data, unsigned *idx);
-int prioq_remove(Prioq *q, void *data, unsigned *idx);
-int prioq_reshuffle(Prioq *q, void *data, unsigned *idx);
-
-void *prioq_peek(Prioq *q) _pure_;
-void *prioq_pop(Prioq *q);
-
-unsigned prioq_size(Prioq *q) _pure_;
-bool prioq_isempty(Prioq *q) _pure_;
diff --git a/src/systemd/src/basic/process-util.c b/src/systemd/src/basic/process-util.c
deleted file mode 100644
index 1412f036..00000000
--- a/src/systemd/src/basic/process-util.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <linux/oom.h>
-#include <sched.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/personality.h>
-#include <sys/prctl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <syslog.h>
-#include <unistd.h>
-#if 0 /* NM_IGNORED */
-#if HAVE_VALGRIND_VALGRIND_H
-#include <valgrind/valgrind.h>
-#endif
-#endif /* NM_IGNORED */
-
-#include "alloc-util.h"
-#include "architecture.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "ioprio.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "process-util.h"
-#include "raw-clone.h"
-#include "signal-util.h"
-#include "stat-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "terminal-util.h"
-#include "user-util.h"
-#include "util.h"
-
-#if 0 /* NM_IGNORED */
-int get_process_state(pid_t pid) {
-        const char *p;
-        char state;
-        int r;
-        _cleanup_free_ char *line = NULL;
-
-        assert(pid >= 0);
-
-        p = procfs_file_alloca(pid, "stat");
-
-        r = read_one_line_file(p, &line);
-        if (r == -ENOENT)
-                return -ESRCH;
-        if (r < 0)
-                return r;
-
-        p = strrchr(line, ')');
-        if (!p)
-                return -EIO;
-
-        p++;
-
-        if (sscanf(p, " %c", &state) != 1)
-                return -EIO;
-
-        return (unsigned char) state;
-}
-
-int get_process_comm(pid_t pid, char **ret) {
-        _cleanup_free_ char *escaped = NULL, *comm = NULL;
-        const char *p;
-        int r;
-
-        assert(ret);
-        assert(pid >= 0);
-
-        escaped = new(char, TASK_COMM_LEN);
-        if (!escaped)
-                return -ENOMEM;
-
-        p = procfs_file_alloca(pid, "comm");
-
-        r = read_one_line_file(p, &comm);
-        if (r == -ENOENT)
-                return -ESRCH;
-        if (r < 0)
-                return r;
-
-        /* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */
-        cellescape(escaped, TASK_COMM_LEN, comm);
-
-        *ret = TAKE_PTR(escaped);
-        return 0;
-}
-
-int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
-        _cleanup_fclose_ FILE *f = NULL;
-        bool space = false;
-        char *k, *ans = NULL;
-        const char *p;
-        int c;
-
-        assert(line);
-        assert(pid >= 0);
-
-        /* Retrieves a process' command line. Replaces unprintable characters while doing so by whitespace (coalescing
-         * multiple sequential ones into one). If max_length is != 0 will return a string of the specified size at most
-         * (the trailing NUL byte does count towards the length here!), abbreviated with a "..." ellipsis. If
-         * comm_fallback is true and the process has no command line set (the case for kernel threads), or has a
-         * command line that resolves to the empty string will return the "comm" name of the process instead.
-         *
-         * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
-         * comm_fallback is false). Returns 0 and sets *line otherwise. */
-
-        p = procfs_file_alloca(pid, "cmdline");
-
-        f = fopen(p, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return -ESRCH;
-                return -errno;
-        }
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        if (max_length == 1) {
-
-                /* If there's only room for one byte, return the empty string */
-                ans = new0(char, 1);
-                if (!ans)
-                        return -ENOMEM;
-
-                *line = ans;
-                return 0;
-
-        } else if (max_length == 0) {
-                size_t len = 0, allocated = 0;
-
-                while ((c = getc(f)) != EOF) {
-
-                        if (!GREEDY_REALLOC(ans, allocated, len+3)) {
-                                free(ans);
-                                return -ENOMEM;
-                        }
-
-                        if (isprint(c)) {
-                                if (space) {
-                                        ans[len++] = ' ';
-                                        space = false;
-                                }
-
-                                ans[len++] = c;
-                        } else if (len > 0)
-                                space = true;
-               }
-
-                if (len > 0)
-                        ans[len] = '\0';
-                else
-                        ans = mfree(ans);
-
-        } else {
-                bool dotdotdot = false;
-                size_t left;
-
-                ans = new(char, max_length);
-                if (!ans)
-                        return -ENOMEM;
-
-                k = ans;
-                left = max_length;
-                while ((c = getc(f)) != EOF) {
-
-                        if (isprint(c)) {
-
-                                if (space) {
-                                        if (left <= 2) {
-                                                dotdotdot = true;
-                                                break;
-                                        }
-
-                                        *(k++) = ' ';
-                                        left--;
-                                        space = false;
-                                }
-
-                                if (left <= 1) {
-                                        dotdotdot = true;
-                                        break;
-                                }
-
-                                *(k++) = (char) c;
-                                left--;
-                        } else if (k > ans)
-                                space = true;
-                }
-
-                if (dotdotdot) {
-                        if (max_length <= 4) {
-                                k = ans;
-                                left = max_length;
-                        } else {
-                                k = ans + max_length - 4;
-                                left = 4;
-
-                                /* Eat up final spaces */
-                                while (k > ans && isspace(k[-1])) {
-                                        k--;
-                                        left++;
-                                }
-                        }
-
-                        strncpy(k, "...", left-1);
-                        k[left-1] = 0;
-                } else
-                        *k = 0;
-        }
-
-        /* Kernel threads have no argv[] */
-        if (isempty(ans)) {
-                _cleanup_free_ char *t = NULL;
-                int h;
-
-                free(ans);
-
-                if (!comm_fallback)
-                        return -ENOENT;
-
-                h = get_process_comm(pid, &t);
-                if (h < 0)
-                        return h;
-
-                if (max_length == 0)
-                        ans = strjoin("[", t, "]");
-                else {
-                        size_t l;
-
-                        l = strlen(t);
-
-                        if (l + 3 <= max_length)
-                                ans = strjoin("[", t, "]");
-                        else if (max_length <= 6) {
-
-                                ans = new(char, max_length);
-                                if (!ans)
-                                        return -ENOMEM;
-
-                                memcpy(ans, "[...]", max_length-1);
-                                ans[max_length-1] = 0;
-                        } else {
-                                t[max_length - 6] = 0;
-
-                                /* Chop off final spaces */
-                                delete_trailing_chars(t, WHITESPACE);
-
-                                ans = strjoin("[", t, "...]");
-                        }
-                }
-                if (!ans)
-                        return -ENOMEM;
-        }
-
-        *line = ans;
-        return 0;
-}
-
-int rename_process(const char name[]) {
-        static size_t mm_size = 0;
-        static char *mm = NULL;
-        bool truncated = false;
-        size_t l;
-
-        /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
-         * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
-         * many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded;
-         * to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be
-         * truncated.
-         *
-         * Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */
-
-        if (isempty(name))
-                return -EINVAL; /* let's not confuse users unnecessarily with an empty name */
-
-        if (!is_main_thread())
-                return -EPERM; /* Let's not allow setting the process name from other threads than the main one, as we
-                                * cache things without locking, and we make assumptions that PR_SET_NAME sets the
-                                * process name that isn't correct on any other threads */
-
-        l = strlen(name);
-
-        /* First step, change the comm field. The main thread's comm is identical to the process comm. This means we
-         * can use PR_SET_NAME, which sets the thread name for the calling thread. */
-        if (prctl(PR_SET_NAME, name) < 0)
-                log_debug_errno(errno, "PR_SET_NAME failed: %m");
-        if (l >= TASK_COMM_LEN) /* Linux process names can be 15 chars at max */
-                truncated = true;
-
-        /* Second step, change glibc's ID of the process name. */
-        if (program_invocation_name) {
-                size_t k;
-
-                k = strlen(program_invocation_name);
-                strncpy(program_invocation_name, name, k);
-                if (l > k)
-                        truncated = true;
-        }
-
-        /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
-         * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
-         * the end. This is the best option for changing /proc/self/cmdline. */
-
-        /* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
-         * CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
-         * present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
-         * PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but
-         * mmap() is not. */
-        if (geteuid() != 0)
-                log_debug("Skipping PR_SET_MM, as we don't have privileges.");
-        else if (mm_size < l+1) {
-                size_t nn_size;
-                char *nn;
-
-                nn_size = PAGE_ALIGN(l+1);
-                nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-                if (nn == MAP_FAILED) {
-                        log_debug_errno(errno, "mmap() failed: %m");
-                        goto use_saved_argv;
-                }
-
-                strncpy(nn, name, nn_size);
-
-                /* Now, let's tell the kernel about this new memory */
-                if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
-                        log_debug_errno(errno, "PR_SET_MM_ARG_START failed, proceeding without: %m");
-                        (void) munmap(nn, nn_size);
-                        goto use_saved_argv;
-                }
-
-                /* And update the end pointer to the new end, too. If this fails, we don't really know what to do, it's
-                 * pretty unlikely that we can rollback, hence we'll just accept the failure, and continue. */
-                if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
-                        log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
-
-                if (mm)
-                        (void) munmap(mm, mm_size);
-
-                mm = nn;
-                mm_size = nn_size;
-        } else {
-                strncpy(mm, name, mm_size);
-
-                /* Update the end pointer, continuing regardless of any failure. */
-                if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0)
-                        log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
-        }
-
-use_saved_argv:
-        /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
-         * it still looks here */
-
-        if (saved_argc > 0) {
-                int i;
-
-                if (saved_argv[0]) {
-                        size_t k;
-
-                        k = strlen(saved_argv[0]);
-                        strncpy(saved_argv[0], name, k);
-                        if (l > k)
-                                truncated = true;
-                }
-
-                for (i = 1; i < saved_argc; i++) {
-                        if (!saved_argv[i])
-                                break;
-
-                        memzero(saved_argv[i], strlen(saved_argv[i]));
-                }
-        }
-
-        return !truncated;
-}
-
-int is_kernel_thread(pid_t pid) {
-        _cleanup_free_ char *line = NULL;
-        unsigned long long flags;
-        size_t l, i;
-        const char *p;
-        char *q;
-        int r;
-
-        if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
-                return 0;
-        if (!pid_is_valid(pid))
-                return -EINVAL;
-
-        p = procfs_file_alloca(pid, "stat");
-        r = read_one_line_file(p, &line);
-        if (r == -ENOENT)
-                return -ESRCH;
-        if (r < 0)
-                return r;
-
-        /* Skip past the comm field */
-        q = strrchr(line, ')');
-        if (!q)
-                return -EINVAL;
-        q++;
-
-        /* Skip 6 fields to reach the flags field */
-        for (i = 0; i < 6; i++) {
-                l = strspn(q, WHITESPACE);
-                if (l < 1)
-                        return -EINVAL;
-                q += l;
-
-                l = strcspn(q, WHITESPACE);
-                if (l < 1)
-                        return -EINVAL;
-                q += l;
-        }
-
-        /* Skip preceeding whitespace */
-        l = strspn(q, WHITESPACE);
-        if (l < 1)
-                return -EINVAL;
-        q += l;
-
-        /* Truncate the rest */
-        l = strcspn(q, WHITESPACE);
-        if (l < 1)
-                return -EINVAL;
-        q[l] = 0;
-
-        r = safe_atollu(q, &flags);
-        if (r < 0)
-                return r;
-
-        return !!(flags & PF_KTHREAD);
-}
-
-int get_process_capeff(pid_t pid, char **capeff) {
-        const char *p;
-        int r;
-
-        assert(capeff);
-        assert(pid >= 0);
-
-        p = procfs_file_alloca(pid, "status");
-
-        r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
-        if (r == -ENOENT)
-                return -ESRCH;
-
-        return r;
-}
-
-static int get_process_link_contents(const char *proc_file, char **name) {
-        int r;
-
-        assert(proc_file);
-        assert(name);
-
-        r = readlink_malloc(proc_file, name);
-        if (r == -ENOENT)
-                return -ESRCH;
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-int get_process_exe(pid_t pid, char **name) {
-        const char *p;
-        char *d;
-        int r;
-
-        assert(pid >= 0);
-
-        p = procfs_file_alloca(pid, "exe");
-        r = get_process_link_contents(p, name);
-        if (r < 0)
-                return r;
-
-        d = endswith(*name, " (deleted)");
-        if (d)
-                *d = '\0';
-
-        return 0;
-}
-
-static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char line[LINE_MAX];
-        const char *p;
-
-        assert(field);
-        assert(uid);
-
-        if (pid < 0)
-                return -EINVAL;
-
-        p = procfs_file_alloca(pid, "status");
-        f = fopen(p, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return -ESRCH;
-                return -errno;
-        }
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        FOREACH_LINE(line, f, return -errno) {
-                char *l;
-
-                l = strstrip(line);
-
-                if (startswith(l, field)) {
-                        l += strlen(field);
-                        l += strspn(l, WHITESPACE);
-
-                        l[strcspn(l, WHITESPACE)] = 0;
-
-                        return parse_uid(l, uid);
-                }
-        }
-
-        return -EIO;
-}
-
-int get_process_uid(pid_t pid, uid_t *uid) {
-
-        if (pid == 0 || pid == getpid_cached()) {
-                *uid = getuid();
-                return 0;
-        }
-
-        return get_process_id(pid, "Uid:", uid);
-}
-
-int get_process_gid(pid_t pid, gid_t *gid) {
-
-        if (pid == 0 || pid == getpid_cached()) {
-                *gid = getgid();
-                return 0;
-        }
-
-        assert_cc(sizeof(uid_t) == sizeof(gid_t));
-        return get_process_id(pid, "Gid:", gid);
-}
-
-int get_process_cwd(pid_t pid, char **cwd) {
-        const char *p;
-
-        assert(pid >= 0);
-
-        p = procfs_file_alloca(pid, "cwd");
-
-        return get_process_link_contents(p, cwd);
-}
-
-int get_process_root(pid_t pid, char **root) {
-        const char *p;
-
-        assert(pid >= 0);
-
-        p = procfs_file_alloca(pid, "root");
-
-        return get_process_link_contents(p, root);
-}
-
-int get_process_environ(pid_t pid, char **env) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *outcome = NULL;
-        int c;
-        const char *p;
-        size_t allocated = 0, sz = 0;
-
-        assert(pid >= 0);
-        assert(env);
-
-        p = procfs_file_alloca(pid, "environ");
-
-        f = fopen(p, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return -ESRCH;
-                return -errno;
-        }
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        while ((c = fgetc(f)) != EOF) {
-                if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
-                        return -ENOMEM;
-
-                if (c == '\0')
-                        outcome[sz++] = '\n';
-                else
-                        sz += cescape_char(c, outcome + sz);
-        }
-
-        if (!outcome) {
-                outcome = strdup("");
-                if (!outcome)
-                        return -ENOMEM;
-        } else
-                outcome[sz] = '\0';
-
-        *env = TAKE_PTR(outcome);
-
-        return 0;
-}
-
-int get_process_ppid(pid_t pid, pid_t *_ppid) {
-        int r;
-        _cleanup_free_ char *line = NULL;
-        long unsigned ppid;
-        const char *p;
-
-        assert(pid >= 0);
-        assert(_ppid);
-
-        if (pid == 0 || pid == getpid_cached()) {
-                *_ppid = getppid();
-                return 0;
-        }
-
-        p = procfs_file_alloca(pid, "stat");
-        r = read_one_line_file(p, &line);
-        if (r == -ENOENT)
-                return -ESRCH;
-        if (r < 0)
-                return r;
-
-        /* Let's skip the pid and comm fields. The latter is enclosed
-         * in () but does not escape any () in its value, so let's
-         * skip over it manually */
-
-        p = strrchr(line, ')');
-        if (!p)
-                return -EIO;
-
-        p++;
-
-        if (sscanf(p, " "
-                   "%*c "  /* state */
-                   "%lu ", /* ppid */
-                   &ppid) != 1)
-                return -EIO;
-
-        if ((long unsigned) (pid_t) ppid != ppid)
-                return -ERANGE;
-
-        *_ppid = (pid_t) ppid;
-
-        return 0;
-}
-
-int wait_for_terminate(pid_t pid, siginfo_t *status) {
-        siginfo_t dummy;
-
-        assert(pid >= 1);
-
-        if (!status)
-                status = &dummy;
-
-        for (;;) {
-                zero(*status);
-
-                if (waitid(P_PID, pid, status, WEXITED) < 0) {
-
-                        if (errno == EINTR)
-                                continue;
-
-                        return negative_errno();
-                }
-
-                return 0;
-        }
-}
-
-/*
- * Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
- *       process, the process was terminated by a signal, or
- *       failed for an unknown reason.
- * >=0 : The process terminated normally, and its exit code is
- *       returned.
- *
- * That is, success is indicated by a return value of zero, and an
- * error is indicated by a non-zero value.
- *
- * A warning is emitted if the process terminates abnormally,
- * and also if it returns non-zero unless check_exit_code is true.
- */
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
-        _cleanup_free_ char *buffer = NULL;
-        siginfo_t status;
-        int r, prio;
-
-        assert(pid > 1);
-
-        if (!name) {
-                r = get_process_comm(pid, &buffer);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid);
-                else
-                        name = buffer;
-        }
-
-        prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG;
-
-        r = wait_for_terminate(pid, &status);
-        if (r < 0)
-                return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name));
-
-        if (status.si_code == CLD_EXITED) {
-                if (status.si_status != EXIT_SUCCESS)
-                        log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG,
-                                 "%s failed with exit status %i.", strna(name), status.si_status);
-                else
-                        log_debug("%s succeeded.", name);
-
-                return status.si_status;
-
-        } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) {
-
-                log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status));
-                return -EPROTO;
-        }
-
-        log_full(prio, "%s failed due to unknown reason.", strna(name));
-        return -EPROTO;
-}
-
-/*
- * Return values:
- *
- * < 0 : wait_for_terminate_with_timeout() failed to get the state of the process, the process timed out, the process
- *       was terminated by a signal, or failed for an unknown reason.
- *
- * >=0 : The process terminated normally with no failures.
- *
- * Success is indicated by a return value of zero, a timeout is indicated by ETIMEDOUT, and all other child failure
- * states are indicated by error is indicated by a non-zero value.
- *
- * This call assumes SIGCHLD has been blocked already, in particular before the child to wait for has been forked off
- * to remain entirely race-free.
- */
-int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
-        sigset_t mask;
-        int r;
-        usec_t until;
-
-        assert_se(sigemptyset(&mask) == 0);
-        assert_se(sigaddset(&mask, SIGCHLD) == 0);
-
-        /* Drop into a sigtimewait-based timeout. Waiting for the
-         * pid to exit. */
-        until = now(CLOCK_MONOTONIC) + timeout;
-        for (;;) {
-                usec_t n;
-                siginfo_t status = {};
-                struct timespec ts;
-
-                n = now(CLOCK_MONOTONIC);
-                if (n >= until)
-                        break;
-
-                r = sigtimedwait(&mask, NULL, timespec_store(&ts, until - n)) < 0 ? -errno : 0;
-                /* Assuming we woke due to the child exiting. */
-                if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
-                        if (status.si_pid == pid) {
-                                /* This is the correct child.*/
-                                if (status.si_code == CLD_EXITED)
-                                        return (status.si_status == 0) ? 0 : -EPROTO;
-                                else
-                                        return -EPROTO;
-                        }
-                }
-                /* Not the child, check for errors and proceed appropriately */
-                if (r < 0) {
-                        switch (r) {
-                        case -EAGAIN:
-                                /* Timed out, child is likely hung. */
-                                return -ETIMEDOUT;
-                        case -EINTR:
-                                /* Received a different signal and should retry */
-                                continue;
-                        default:
-                                /* Return any unexpected errors */
-                                return r;
-                        }
-                }
-        }
-
-        return -EPROTO;
-}
-
-void sigkill_wait(pid_t pid) {
-        assert(pid > 1);
-
-        if (kill(pid, SIGKILL) > 0)
-                (void) wait_for_terminate(pid, NULL);
-}
-
-void sigkill_waitp(pid_t *pid) {
-        PROTECT_ERRNO;
-
-        if (!pid)
-                return;
-        if (*pid <= 1)
-                return;
-
-        sigkill_wait(*pid);
-}
-
-void sigterm_wait(pid_t pid) {
-        assert(pid > 1);
-
-        if (kill_and_sigcont(pid, SIGTERM) > 0)
-                (void) wait_for_terminate(pid, NULL);
-}
-
-int kill_and_sigcont(pid_t pid, int sig) {
-        int r;
-
-        r = kill(pid, sig) < 0 ? -errno : 0;
-
-        /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
-         * affected by a process being suspended anyway. */
-        if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
-                (void) kill(pid, SIGCONT);
-
-        return r;
-}
-
-int getenv_for_pid(pid_t pid, const char *field, char **ret) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char *value = NULL;
-        bool done = false;
-        const char *path;
-        size_t l;
-
-        assert(pid >= 0);
-        assert(field);
-        assert(ret);
-
-        if (pid == 0 || pid == getpid_cached()) {
-                const char *e;
-
-                e = getenv(field);
-                if (!e) {
-                        *ret = NULL;
-                        return 0;
-                }
-
-                value = strdup(e);
-                if (!value)
-                        return -ENOMEM;
-
-                *ret = value;
-                return 1;
-        }
-
-        path = procfs_file_alloca(pid, "environ");
-
-        f = fopen(path, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return -ESRCH;
-
-                return -errno;
-        }
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        l = strlen(field);
-
-        do {
-                char line[LINE_MAX];
-                size_t i;
-
-                for (i = 0; i < sizeof(line)-1; i++) {
-                        int c;
-
-                        c = getc(f);
-                        if (_unlikely_(c == EOF)) {
-                                done = true;
-                                break;
-                        } else if (c == 0)
-                                break;
-
-                        line[i] = c;
-                }
-                line[i] = 0;
-
-                if (strneq(line, field, l) && line[l] == '=') {
-                        value = strdup(line + l + 1);
-                        if (!value)
-                                return -ENOMEM;
-
-                        *ret = value;
-                        return 1;
-                }
-
-        } while (!done);
-
-        *ret = NULL;
-        return 0;
-}
-
-bool pid_is_unwaited(pid_t pid) {
-        /* Checks whether a PID is still valid at all, including a zombie */
-
-        if (pid < 0)
-                return false;
-
-        if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
-                return true;
-
-        if (pid == getpid_cached())
-                return true;
-
-        if (kill(pid, 0) >= 0)
-                return true;
-
-        return errno != ESRCH;
-}
-
-bool pid_is_alive(pid_t pid) {
-        int r;
-
-        /* Checks whether a PID is still valid and not a zombie */
-
-        if (pid < 0)
-                return false;
-
-        if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
-                return true;
-
-        if (pid == getpid_cached())
-                return true;
-
-        r = get_process_state(pid);
-        if (IN_SET(r, -ESRCH, 'Z'))
-                return false;
-
-        return true;
-}
-
-int pid_from_same_root_fs(pid_t pid) {
-        const char *root;
-
-        if (pid < 0)
-                return false;
-
-        if (pid == 0 || pid == getpid_cached())
-                return true;
-
-        root = procfs_file_alloca(pid, "root");
-
-        return files_same(root, "/proc/1/root", 0);
-}
-#endif /* NM_IGNORED */
-
-bool is_main_thread(void) {
-        static thread_local int cached = 0;
-
-        if (_unlikely_(cached == 0))
-                cached = getpid_cached() == gettid() ? 1 : -1;
-
-        return cached > 0;
-}
-
-#if 0 /* NM_IGNORED */
-_noreturn_ void freeze(void) {
-
-        log_close();
-
-        /* Make sure nobody waits for us on a socket anymore */
-        close_all_fds(NULL, 0);
-
-        sync();
-
-        /* Let's not freeze right away, but keep reaping zombies. */
-        for (;;) {
-                int r;
-                siginfo_t si = {};
-
-                r = waitid(P_ALL, 0, &si, WEXITED);
-                if (r < 0 && errno != EINTR)
-                        break;
-        }
-
-        /* waitid() failed with an unexpected error, things are really borked. Freeze now! */
-        for (;;)
-                pause();
-}
-
-bool oom_score_adjust_is_valid(int oa) {
-        return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
-}
-
-unsigned long personality_from_string(const char *p) {
-        int architecture;
-
-        if (!p)
-                return PERSONALITY_INVALID;
-
-        /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
-         * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
-         * the same register size. */
-
-        architecture = architecture_from_string(p);
-        if (architecture < 0)
-                return PERSONALITY_INVALID;
-
-        if (architecture == native_architecture())
-                return PER_LINUX;
-#ifdef SECONDARY_ARCHITECTURE
-        if (architecture == SECONDARY_ARCHITECTURE)
-                return PER_LINUX32;
-#endif
-
-        return PERSONALITY_INVALID;
-}
-
-const char* personality_to_string(unsigned long p) {
-        int architecture = _ARCHITECTURE_INVALID;
-
-        if (p == PER_LINUX)
-                architecture = native_architecture();
-#ifdef SECONDARY_ARCHITECTURE
-        else if (p == PER_LINUX32)
-                architecture = SECONDARY_ARCHITECTURE;
-#endif
-
-        if (architecture < 0)
-                return NULL;
-
-        return architecture_to_string(architecture);
-}
-
-int safe_personality(unsigned long p) {
-        int ret;
-
-        /* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno,
-         * and in others as negative return value containing an errno-like value. Let's work around this: this is a
-         * wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and
-         * the return value indicating the same issue, so that we are definitely on the safe side.
-         *
-         * See https://github.com/systemd/systemd/issues/6737 */
-
-        errno = 0;
-        ret = personality(p);
-        if (ret < 0) {
-                if (errno != 0)
-                        return -errno;
-
-                errno = -ret;
-        }
-
-        return ret;
-}
-
-int opinionated_personality(unsigned long *ret) {
-        int current;
-
-        /* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit
-         * opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
-         * two most relevant personalities: PER_LINUX and PER_LINUX32. */
-
-        current = safe_personality(PERSONALITY_INVALID);
-        if (current < 0)
-                return current;
-
-        if (((unsigned long) current & 0xffff) == PER_LINUX32)
-                *ret = PER_LINUX32;
-        else
-                *ret = PER_LINUX;
-
-        return 0;
-}
-
-void valgrind_summary_hack(void) {
-#if HAVE_VALGRIND_VALGRIND_H
-        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
-                pid_t pid;
-                pid = raw_clone(SIGCHLD);
-                if (pid < 0)
-                        log_emergency_errno(errno, "Failed to fork off valgrind helper: %m");
-                else if (pid == 0)
-                        exit(EXIT_SUCCESS);
-                else {
-                        log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
-                        (void) wait_for_terminate(pid, NULL);
-                }
-        }
-#endif
-}
-
-int pid_compare_func(const void *a, const void *b) {
-        const pid_t *p = a, *q = b;
-
-        /* Suitable for usage in qsort() */
-        return CMP(*p, *q);
-}
-
-int ioprio_parse_priority(const char *s, int *ret) {
-        int i, r;
-
-        assert(s);
-        assert(ret);
-
-        r = safe_atoi(s, &i);
-        if (r < 0)
-                return r;
-
-        if (!ioprio_priority_is_valid(i))
-                return -EINVAL;
-
-        *ret = i;
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-/* The cached PID, possible values:
- *
- *     == UNSET [0]  → cache not initialized yet
- *     == BUSY [-1]  → some thread is initializing it at the moment
- *     any other     → the cached PID
- */
-
-#define CACHED_PID_UNSET ((pid_t) 0)
-#define CACHED_PID_BUSY ((pid_t) -1)
-
-static pid_t cached_pid = CACHED_PID_UNSET;
-
-void reset_cached_pid(void) {
-        /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
-        cached_pid = CACHED_PID_UNSET;
-}
-
-/* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc
- * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against
- * libpthread, as it is part of glibc anyway. */
-extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle);
-extern void* __dso_handle __attribute__ ((__weak__));
-
-pid_t getpid_cached(void) {
-        static bool installed = false;
-        pid_t current_value;
-
-        /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
-         * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
-         * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when
-         * objects were used across fork()s. With this caching the old behaviour is somewhat restored.
-         *
-         * https://bugzilla.redhat.com/show_bug.cgi?id=1443976
-         * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e
-         */
-
-        current_value = __sync_val_compare_and_swap(&cached_pid, CACHED_PID_UNSET, CACHED_PID_BUSY);
-
-        switch (current_value) {
-
-        case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
-                pid_t new_pid;
-
-                new_pid = raw_getpid();
-
-                if (!installed) {
-                        /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's
-                         * only half-documented (glibc doesn't document it but LSB does — though only superficially)
-                         * we'll check for errors only in the most generic fashion possible. */
-
-                        if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) {
-                                /* OOM? Let's try again later */
-                                cached_pid = CACHED_PID_UNSET;
-                                return new_pid;
-                        }
-
-                        installed = true;
-                }
-
-                cached_pid = new_pid;
-                return new_pid;
-        }
-
-        case CACHED_PID_BUSY: /* Somebody else is currently initializing */
-                return raw_getpid();
-
-        default: /* Properly initialized */
-                return current_value;
-        }
-}
-
-#if 0 /* NM_IGNORED */
-int must_be_root(void) {
-
-        if (geteuid() == 0)
-                return 0;
-
-        log_error("Need to be root.");
-        return -EPERM;
-}
-
-int safe_fork_full(
-                const char *name,
-                const int except_fds[],
-                size_t n_except_fds,
-                ForkFlags flags,
-                pid_t *ret_pid) {
-
-        pid_t original_pid, pid;
-        sigset_t saved_ss, ss;
-        bool block_signals = false;
-        int prio, r;
-
-        /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
-         * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */
-
-        prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG;
-
-        original_pid = getpid_cached();
-
-        if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG)) {
-
-                /* We temporarily block all signals, so that the new child has them blocked initially. This way, we can
-                 * be sure that SIGTERMs are not lost we might send to the child. */
-
-                if (sigfillset(&ss) < 0)
-                        return log_full_errno(prio, errno, "Failed to reset signal set: %m");
-
-                block_signals = true;
-
-        } else if (flags & FORK_WAIT) {
-
-                /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
-
-                if (sigemptyset(&ss) < 0)
-                        return log_full_errno(prio, errno, "Failed to clear signal set: %m");
-
-                if (sigaddset(&ss, SIGCHLD) < 0)
-                        return log_full_errno(prio, errno, "Failed to add SIGCHLD to signal set: %m");
-
-                block_signals = true;
-        }
-
-        if (block_signals)
-                if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0)
-                        return log_full_errno(prio, errno, "Failed to set signal mask: %m");
-
-        if (flags & FORK_NEW_MOUNTNS)
-                pid = raw_clone(SIGCHLD|CLONE_NEWNS);
-        else
-                pid = fork();
-        if (pid < 0) {
-                r = -errno;
-
-                if (block_signals) /* undo what we did above */
-                        (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
-
-                return log_full_errno(prio, r, "Failed to fork: %m");
-        }
-        if (pid > 0) {
-                /* We are in the parent process */
-
-                log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
-
-                if (flags & FORK_WAIT) {
-                        r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
-                        if (r < 0)
-                                return r;
-                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
-                                return -EPROTO;
-                }
-
-                if (block_signals) /* undo what we did above */
-                        (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
-
-                if (ret_pid)
-                        *ret_pid = pid;
-
-                return 1;
-        }
-
-        /* We are in the child process */
-
-        if (flags & FORK_REOPEN_LOG) {
-                /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
-                log_close();
-                log_set_open_when_needed(true);
-        }
-
-        if (name) {
-                r = rename_process(name);
-                if (r < 0)
-                        log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG,
-                                       r, "Failed to rename process, ignoring: %m");
-        }
-
-        if (flags & FORK_DEATHSIG)
-                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) {
-                        log_full_errno(prio, errno, "Failed to set death signal: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-        if (flags & FORK_RESET_SIGNALS) {
-                r = reset_all_signal_handlers();
-                if (r < 0) {
-                        log_full_errno(prio, r, "Failed to reset signal handlers: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                /* This implicitly undoes the signal mask stuff we did before the fork()ing above */
-                r = reset_signal_mask();
-                if (r < 0) {
-                        log_full_errno(prio, r, "Failed to reset signal mask: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        } else if (block_signals) { /* undo what we did above */
-                if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) {
-                        log_full_errno(prio, errno, "Failed to restore signal mask: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
-        if (flags & FORK_DEATHSIG) {
-                pid_t ppid;
-                /* Let's see if the parent PID is still the one we started from? If not, then the parent
-                 * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */
-
-                ppid = getppid();
-                if (ppid == 0)
-                        /* Parent is in a differn't PID namespace. */;
-                else if (ppid != original_pid) {
-                        log_debug("Parent died early, raising SIGTERM.");
-                        (void) raise(SIGTERM);
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
-        if (FLAGS_SET(flags, FORK_NEW_MOUNTNS | FORK_MOUNTNS_SLAVE)) {
-
-                /* Optionally, make sure we never propagate mounts to the host. */
-
-                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
-                        log_full_errno(prio, errno, "Failed to remount root directory as MS_SLAVE: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
-        if (flags & FORK_CLOSE_ALL_FDS) {
-                /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
-                log_close();
-
-                r = close_all_fds(except_fds, n_except_fds);
-                if (r < 0) {
-                        log_full_errno(prio, r, "Failed to close all file descriptors: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
-        /* When we were asked to reopen the logs, do so again now */
-        if (flags & FORK_REOPEN_LOG) {
-                log_open();
-                log_set_open_when_needed(false);
-        }
-
-        if (flags & FORK_NULL_STDIO) {
-                r = make_null_stdio();
-                if (r < 0) {
-                        log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
-        if (ret_pid)
-                *ret_pid = getpid_cached();
-
-        return 0;
-}
-
-int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
-        bool stdout_is_tty, stderr_is_tty;
-        size_t n, i;
-        va_list ap;
-        char **l;
-        int r;
-
-        assert(path);
-
-        /* Spawns a temporary TTY agent, making sure it goes away when we go away */
-
-        r = safe_fork_full(name, except, n_except, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS, ret_pid);
-        if (r < 0)
-                return r;
-        if (r > 0)
-                return 0;
-
-        /* In the child: */
-
-        stdout_is_tty = isatty(STDOUT_FILENO);
-        stderr_is_tty = isatty(STDERR_FILENO);
-
-        if (!stdout_is_tty || !stderr_is_tty) {
-                int fd;
-
-                /* Detach from stdout/stderr. and reopen
-                 * /dev/tty for them. This is important to
-                 * ensure that when systemctl is started via
-                 * popen() or a similar call that expects to
-                 * read EOF we actually do generate EOF and
-                 * not delay this indefinitely by because we
-                 * keep an unused copy of stdin around. */
-                fd = open("/dev/tty", O_WRONLY);
-                if (fd < 0) {
-                        log_error_errno(errno, "Failed to open /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
-                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
-                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                safe_close_above_stdio(fd);
-        }
-
-        /* Count arguments */
-        va_start(ap, path);
-        for (n = 0; va_arg(ap, char*); n++)
-                ;
-        va_end(ap);
-
-        /* Allocate strv */
-        l = newa(char*, n + 1);
-
-        /* Fill in arguments */
-        va_start(ap, path);
-        for (i = 0; i <= n; i++)
-                l[i] = va_arg(ap, char*);
-        va_end(ap);
-
-        execv(path, l);
-        _exit(EXIT_FAILURE);
-}
-
-int set_oom_score_adjust(int value) {
-        char t[DECIMAL_STR_MAX(int)];
-
-        sprintf(t, "%i", value);
-
-        return write_string_file("/proc/self/oom_score_adj", t,
-                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
-}
-
-static const char *const ioprio_class_table[] = {
-        [IOPRIO_CLASS_NONE] = "none",
-        [IOPRIO_CLASS_RT] = "realtime",
-        [IOPRIO_CLASS_BE] = "best-effort",
-        [IOPRIO_CLASS_IDLE] = "idle"
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES);
-
-static const char *const sigchld_code_table[] = {
-        [CLD_EXITED] = "exited",
-        [CLD_KILLED] = "killed",
-        [CLD_DUMPED] = "dumped",
-        [CLD_TRAPPED] = "trapped",
-        [CLD_STOPPED] = "stopped",
-        [CLD_CONTINUED] = "continued",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
-
-static const char* const sched_policy_table[] = {
-        [SCHED_OTHER] = "other",
-        [SCHED_BATCH] = "batch",
-        [SCHED_IDLE] = "idle",
-        [SCHED_FIFO] = "fifo",
-        [SCHED_RR] = "rr"
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/process-util.h b/src/systemd/src/basic/process-util.h
deleted file mode 100644
index e11164bd..00000000
--- a/src/systemd/src/basic/process-util.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <alloca.h>
-#include <errno.h>
-#include <sched.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-
-#include "format-util.h"
-#include "ioprio.h"
-#include "macro.h"
-#include "time-util.h"
-
-#define procfs_file_alloca(pid, field)                                  \
-        ({                                                              \
-                pid_t _pid_ = (pid);                                    \
-                const char *_r_;                                        \
-                if (_pid_ == 0) {                                       \
-                        _r_ = ("/proc/self/" field);                    \
-                } else {                                                \
-                        _r_ = alloca(STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
-                        sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_);                       \
-                }                                                       \
-                _r_;                                                    \
-        })
-
-int get_process_state(pid_t pid);
-int get_process_comm(pid_t pid, char **name);
-int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
-int get_process_exe(pid_t pid, char **name);
-int get_process_uid(pid_t pid, uid_t *uid);
-int get_process_gid(pid_t pid, gid_t *gid);
-int get_process_capeff(pid_t pid, char **capeff);
-int get_process_cwd(pid_t pid, char **cwd);
-int get_process_root(pid_t pid, char **root);
-int get_process_environ(pid_t pid, char **environ);
-int get_process_ppid(pid_t pid, pid_t *ppid);
-
-int wait_for_terminate(pid_t pid, siginfo_t *status);
-
-typedef enum WaitFlags {
-        WAIT_LOG_ABNORMAL             = 1 << 0,
-        WAIT_LOG_NON_ZERO_EXIT_STATUS = 1 << 1,
-
-        /* A shortcut for requesting the most complete logging */
-        WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS,
-} WaitFlags;
-
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags);
-int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout);
-
-void sigkill_wait(pid_t pid);
-void sigkill_waitp(pid_t *pid);
-void sigterm_wait(pid_t pid);
-
-int kill_and_sigcont(pid_t pid, int sig);
-
-int rename_process(const char name[]);
-int is_kernel_thread(pid_t pid);
-
-int getenv_for_pid(pid_t pid, const char *field, char **_value);
-
-bool pid_is_alive(pid_t pid);
-bool pid_is_unwaited(pid_t pid);
-int pid_from_same_root_fs(pid_t pid);
-
-bool is_main_thread(void);
-
-_noreturn_ void freeze(void);
-
-bool oom_score_adjust_is_valid(int oa);
-
-#ifndef PERSONALITY_INVALID
-/* personality(7) documents that 0xffffffffUL is used for querying the
- * current personality, hence let's use that here as error
- * indicator. */
-#define PERSONALITY_INVALID 0xffffffffLU
-#endif
-
-unsigned long personality_from_string(const char *p);
-const char *personality_to_string(unsigned long);
-
-int safe_personality(unsigned long p);
-int opinionated_personality(unsigned long *ret);
-
-int ioprio_class_to_string_alloc(int i, char **s);
-int ioprio_class_from_string(const char *s);
-
-const char *sigchld_code_to_string(int i) _const_;
-int sigchld_code_from_string(const char *s) _pure_;
-
-int sched_policy_to_string_alloc(int i, char **s);
-int sched_policy_from_string(const char *s);
-
-static inline pid_t PTR_TO_PID(const void *p) {
-        return (pid_t) ((uintptr_t) p);
-}
-
-static inline void* PID_TO_PTR(pid_t pid) {
-        return (void*) ((uintptr_t) pid);
-}
-
-void valgrind_summary_hack(void);
-
-int pid_compare_func(const void *a, const void *b);
-
-#if 0 /* NM_IGNORED */
-static inline bool nice_is_valid(int n) {
-        return n >= PRIO_MIN && n < PRIO_MAX;
-}
-
-static inline bool sched_policy_is_valid(int i) {
-        return IN_SET(i, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RR);
-}
-
-static inline bool sched_priority_is_valid(int i) {
-        return i >= 0 && i <= sched_get_priority_max(SCHED_RR);
-}
-
-static inline bool ioprio_class_is_valid(int i) {
-        return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
-}
-
-static inline bool ioprio_priority_is_valid(int i) {
-        return i >= 0 && i < IOPRIO_BE_NR;
-}
-
-static inline bool pid_is_valid(pid_t p) {
-        return p > 0;
-}
-
-static inline int sched_policy_to_string_alloc_with_check(int n, char **s) {
-        if (!sched_policy_is_valid(n))
-                return -EINVAL;
-
-        return sched_policy_to_string_alloc(n, s);
-}
-#endif /* NM_IGNORED */
-
-int ioprio_parse_priority(const char *s, int *ret);
-
-pid_t getpid_cached(void);
-void reset_cached_pid(void);
-
-int must_be_root(void);
-
-typedef enum ForkFlags {
-        FORK_RESET_SIGNALS = 1 << 0,
-        FORK_CLOSE_ALL_FDS = 1 << 1,
-        FORK_DEATHSIG      = 1 << 2,
-        FORK_NULL_STDIO    = 1 << 3,
-        FORK_REOPEN_LOG    = 1 << 4,
-        FORK_LOG           = 1 << 5,
-        FORK_WAIT          = 1 << 6,
-        FORK_NEW_MOUNTNS   = 1 << 7,
-        FORK_MOUNTNS_SLAVE = 1 << 8,
-} ForkFlags;
-
-int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
-
-static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
-        return safe_fork_full(name, NULL, 0, flags, ret_pid);
-}
-
-int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...);
-
-int set_oom_score_adjust(int value);
-
-#if SIZEOF_PID_T == 4
-/* The highest possibly (theoretic) pid_t value on this architecture. */
-#define PID_T_MAX ((pid_t) INT32_MAX)
-/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value
- * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the
- * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by
- * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since
- * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at
- * least to define them here too. */
-#define TASKS_MAX 4194303U
-#elif SIZEOF_PID_T == 2
-#define PID_T_MAX ((pid_t) INT16_MAX)
-#define TASKS_MAX 32767U
-#else
-#error "Unknown pid_t size"
-#endif
-
-assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX)
-
-/* Like TAKE_PTR() but for child PIDs, resetting them to 0 */
-#define TAKE_PID(pid)                           \
-        ({                                      \
-                pid_t _pid_ = (pid);            \
-                (pid) = 0;                      \
-                _pid_;                          \
-        })
diff --git a/src/systemd/src/basic/random-util.c b/src/systemd/src/basic/random-util.c
deleted file mode 100644
index 5c07e067..00000000
--- a/src/systemd/src/basic/random-util.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#ifdef __x86_64__
-#include <cpuid.h>
-#endif
-
-#include <elf.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/random.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-#if HAVE_SYS_AUXV_H
-#  include <sys/auxv.h>
-#endif
-
-#if USE_SYS_RANDOM_H
-#  include <sys/random.h>
-#else
-#  include <linux/random.h>
-#endif
-
-#include "fd-util.h"
-#include "io-util.h"
-#include "missing.h"
-#include "random-util.h"
-#include "time-util.h"
-
-
-int rdrand64(uint64_t *ret) {
-
-#ifdef __x86_64__
-        static int have_rdrand = -1;
-        unsigned char err;
-
-        if (have_rdrand < 0) {
-                uint32_t eax, ebx, ecx, edx;
-
-                /* Check if RDRAND is supported by the CPU */
-                if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) {
-                        have_rdrand = false;
-                        return -EOPNOTSUPP;
-                }
-
-                have_rdrand = !!(ecx & (1U << 30));
-        }
-
-        if (have_rdrand == 0)
-                return -EOPNOTSUPP;
-
-        asm volatile("rdrand %0;"
-                     "setc %1"
-                     : "=r" (*ret),
-                       "=qm" (err));
-        if (!err)
-                return -EAGAIN;
-
-        return 0;
-#else
-        return -EOPNOTSUPP;
-#endif
-}
-
-int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
-        static int have_syscall = -1;
-
-        _cleanup_close_ int fd = -1;
-        size_t already_done = 0;
-        int r;
-
-        /* Gathers some randomness from the kernel. This call will never block. If
-         * high_quality_required, it will always return some data from the kernel,
-         * regardless of whether the random pool is fully initialized or not.
-         * Otherwise, it will return success if at least some random bytes were
-         * successfully acquired, and an error if the kernel has no entropy whatsover
-         * for us. */
-
-        /* Use the getrandom() syscall unless we know we don't have it. */
-        if (have_syscall != 0 && !HAS_FEATURE_MEMORY_SANITIZER) {
-#if !HAVE_GETRANDOM
-                /* NetworkManager Note: systemd calls the syscall directly in this case. Don't add that workaround.
-                 * If you don't compile against a libc that provides getrandom(), you don't get it. */
-                r = -1;
-                errno = ENOSYS;
-#else
-                r = getrandom(p, n, GRND_NONBLOCK);
-#endif
-                if (r > 0) {
-                        have_syscall = true;
-                        if ((size_t) r == n)
-                                return 0;
-                        if (!high_quality_required) {
-                                /* Fill in the remaining bytes using pseudorandom values */
-                                pseudorandom_bytes((uint8_t*) p + r, n - r);
-                                return 0;
-                        }
-
-                        already_done = r;
-                } else if (errno == ENOSYS)
-                          /* We lack the syscall, continue with reading from /dev/urandom. */
-                          have_syscall = false;
-                else if (errno == EAGAIN) {
-                        /* The kernel has no entropy whatsoever. Let's remember to
-                         * use the syscall the next time again though.
-                         *
-                         * If high_quality_required is false, return an error so that
-                         * random_bytes() can produce some pseudorandom
-                         * bytes. Otherwise, fall back to /dev/urandom, which we know
-                         * is empty, but the kernel will produce some bytes for us on
-                         * a best-effort basis. */
-                        have_syscall = true;
-
-                        if (!high_quality_required) {
-                                uint64_t u;
-                                size_t k;
-
-                                /* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality
-                                 * randomness is not required, as we don't trust it (who does?). Note that we only do a
-                                 * single iteration of RDRAND here, even though the Intel docs suggest calling this in
-                                 * a tight loop of 10 invocatins or so. That's because we don't really care about the
-                                 * quality here. */
-
-                                if (rdrand64(&u) < 0)
-                                        return -ENODATA;
-
-                                k = MIN(n, sizeof(u));
-                                memcpy(p, &u, k);
-
-                                /* We only get 64bit out of RDRAND, the rest let's fill up with pseudo-random crap. */
-                                pseudorandom_bytes((uint8_t*) p + k, n - k);
-                                return 0;
-                        }
-                } else
-                        return -errno;
-        }
-
-        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-        if (fd < 0)
-                return errno == ENOENT ? -ENOSYS : -errno;
-
-        return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
-}
-
-void initialize_srand(void) {
-        static bool srand_called = false;
-        unsigned x;
-#if HAVE_SYS_AUXV_H
-        void *auxv;
-#endif
-
-        if (srand_called)
-                return;
-
-#if HAVE_SYS_AUXV_H
-        /* The kernel provides us with 16 bytes of entropy in auxv, so let's
-         * try to make use of that to seed the pseudo-random generator. It's
-         * better than nothing... */
-
-        auxv = (void*) getauxval(AT_RANDOM);
-        if (auxv) {
-                assert_cc(sizeof(x) <= 16);
-                memcpy(&x, auxv, sizeof(x));
-        } else
-#endif
-                x = 0;
-
-        x ^= (unsigned) now(CLOCK_REALTIME);
-        x ^= (unsigned) gettid();
-
-        srand(x);
-        srand_called = true;
-}
-
-/* INT_MAX gives us only 31 bits, so use 24 out of that. */
-#if RAND_MAX >= INT_MAX
-#  define RAND_STEP 3
-#else
-/* SHORT_INT_MAX or lower gives at most 15 bits, we just just 8 out of that. */
-#  define RAND_STEP 1
-#endif
-
-void pseudorandom_bytes(void *p, size_t n) {
-        uint8_t *q;
-
-        initialize_srand();
-
-        for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) {
-                unsigned rr;
-
-                rr = (unsigned) rand();
-
-#if RAND_STEP >= 3
-                if ((size_t) (q - (uint8_t*) p + 2) < n)
-                        q[2] = rr >> 16;
-#endif
-#if RAND_STEP >= 2
-                if ((size_t) (q - (uint8_t*) p + 1) < n)
-                        q[1] = rr >> 8;
-#endif
-                q[0] = rr;
-        }
-}
-
-void random_bytes(void *p, size_t n) {
-        int r;
-
-        r = acquire_random_bytes(p, n, false);
-        if (r >= 0)
-                return;
-
-        /* If some idiot made /dev/urandom unavailable to us, or the
-         * kernel has no entropy, use a PRNG instead. */
-        return pseudorandom_bytes(p, n);
-}
diff --git a/src/systemd/src/basic/random-util.h b/src/systemd/src/basic/random-util.h
deleted file mode 100644
index affcc9ac..00000000
--- a/src/systemd/src/basic/random-util.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-int acquire_random_bytes(void *p, size_t n, bool high_quality_required);
-void pseudorandom_bytes(void *p, size_t n);
-void random_bytes(void *p, size_t n);
-void initialize_srand(void);
-
-static inline uint64_t random_u64(void) {
-        uint64_t u;
-        random_bytes(&u, sizeof(u));
-        return u;
-}
-
-static inline uint32_t random_u32(void) {
-        uint32_t u;
-        random_bytes(&u, sizeof(u));
-        return u;
-}
-
-int rdrand64(uint64_t *ret);
diff --git a/src/systemd/src/basic/refcnt.h b/src/systemd/src/basic/refcnt.h
deleted file mode 100644
index d2be6086..00000000
--- a/src/systemd/src/basic/refcnt.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-/* A type-safe atomic refcounter.
- *
- * DO NOT USE THIS UNLESS YOU ACTUALLY CARE ABOUT THREAD SAFETY! */
-
-typedef struct {
-        volatile unsigned _value;
-} RefCount;
-
-#define REFCNT_GET(r) ((r)._value)
-#define REFCNT_INC(r) (__sync_add_and_fetch(&(r)._value, 1))
-#define REFCNT_DEC(r) (__sync_sub_and_fetch(&(r)._value, 1))
-
-#define REFCNT_INIT ((RefCount) { ._value = 1 })
diff --git a/src/systemd/src/basic/set.h b/src/systemd/src/basic/set.h
deleted file mode 100644
index 66471381..00000000
--- a/src/systemd/src/basic/set.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include "extract-word.h"
-#include "hashmap.h"
-#include "macro.h"
-
-Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
-#define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS)
-
-static inline Set *set_free(Set *s) {
-        internal_hashmap_free(HASHMAP_BASE(s));
-        return NULL;
-}
-
-static inline Set *set_free_free(Set *s) {
-        internal_hashmap_free_free(HASHMAP_BASE(s));
-        return NULL;
-}
-
-/* no set_free_free_free */
-
-static inline Set *set_copy(Set *s) {
-        return (Set*) internal_hashmap_copy(HASHMAP_BASE(s));
-}
-
-int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
-#define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
-
-int set_put(Set *s, const void *key);
-/* no set_update */
-/* no set_replace */
-static inline void *set_get(Set *s, void *key) {
-        return internal_hashmap_get(HASHMAP_BASE(s), key);
-}
-/* no set_get2 */
-
-static inline bool set_contains(Set *s, const void *key) {
-        return internal_hashmap_contains(HASHMAP_BASE(s), key);
-}
-
-static inline void *set_remove(Set *s, const void *key) {
-        return internal_hashmap_remove(HASHMAP_BASE(s), key);
-}
-
-/* no set_remove2 */
-/* no set_remove_value */
-int set_remove_and_put(Set *s, const void *old_key, const void *new_key);
-/* no set_remove_and_replace */
-int set_merge(Set *s, Set *other);
-
-static inline int set_reserve(Set *h, unsigned entries_add) {
-        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
-}
-
-static inline int set_move(Set *s, Set *other) {
-        return internal_hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other));
-}
-
-static inline int set_move_one(Set *s, Set *other, const void *key) {
-        return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key);
-}
-
-static inline unsigned set_size(Set *s) {
-        return internal_hashmap_size(HASHMAP_BASE(s));
-}
-
-static inline bool set_isempty(Set *s) {
-        return set_size(s) == 0;
-}
-
-static inline unsigned set_buckets(Set *s) {
-        return internal_hashmap_buckets(HASHMAP_BASE(s));
-}
-
-bool set_iterate(Set *s, Iterator *i, void **value);
-
-static inline void set_clear(Set *s) {
-        internal_hashmap_clear(HASHMAP_BASE(s));
-}
-
-static inline void set_clear_free(Set *s) {
-        internal_hashmap_clear_free(HASHMAP_BASE(s));
-}
-
-/* no set_clear_free_free */
-
-static inline void *set_steal_first(Set *s) {
-        return internal_hashmap_steal_first(HASHMAP_BASE(s));
-}
-
-#define set_clear_with_destructor(_s, _f)               \
-        ({                                              \
-                void *_item;                            \
-                while ((_item = set_steal_first(_s)))   \
-                        _f(_item);                      \
-        })
-#define set_free_with_destructor(_s, _f)                \
-        ({                                              \
-                set_clear_with_destructor(_s, _f);      \
-                set_free(_s);                           \
-        })
-
-/* no set_steal_first_key */
-/* no set_first_key */
-
-static inline void *set_first(Set *s) {
-        return internal_hashmap_first(HASHMAP_BASE(s));
-}
-
-/* no set_next */
-
-static inline char **set_get_strv(Set *s) {
-        return internal_hashmap_get_strv(HASHMAP_BASE(s));
-}
-
-int set_consume(Set *s, void *value);
-int set_put_strdup(Set *s, const char *p);
-int set_put_strdupv(Set *s, char **l);
-int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
-
-#define SET_FOREACH(e, s, i) \
-        for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
-
-#define SET_FOREACH_MOVE(e, d, s)                                       \
-        for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); )
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
-
-#define _cleanup_set_free_ _cleanup_(set_freep)
-#define _cleanup_set_free_free_ _cleanup_(set_free_freep)
diff --git a/src/systemd/src/basic/signal-util.h b/src/systemd/src/basic/signal-util.h
deleted file mode 100644
index 92f2804c..00000000
--- a/src/systemd/src/basic/signal-util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <signal.h>
-
-#include "macro.h"
-
-int reset_all_signal_handlers(void);
-int reset_signal_mask(void);
-
-int ignore_signals(int sig, ...);
-int default_signals(int sig, ...);
-int sigaction_many(const struct sigaction *sa, ...);
-
-int sigset_add_many(sigset_t *ss, ...);
-int sigprocmask_many(int how, sigset_t *old, ...);
-
-const char *signal_to_string(int i) _const_;
-int signal_from_string(const char *s) _pure_;
-
-void nop_signal_handler(int sig);
-
-static inline void block_signals_reset(sigset_t *ss) {
-        assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
-}
-
-#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); \
-                _t;                                                                \
-        })
-
-static inline bool SIGNAL_VALID(int signo) {
-        return signo > 0 && signo < _NSIG;
-}
-
-static inline const char* signal_to_string_with_check(int n) {
-        if (!SIGNAL_VALID(n))
-                return NULL;
-
-        return signal_to_string(n);
-}
diff --git a/src/systemd/src/basic/siphash24.h b/src/systemd/src/basic/siphash24.h
deleted file mode 100644
index 77bb9a8c..00000000
--- a/src/systemd/src/basic/siphash24.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#if 0 /* NM_IGNORED */
-struct siphash {
-        uint64_t v0;
-        uint64_t v1;
-        uint64_t v2;
-        uint64_t v3;
-        uint64_t padding;
-        size_t inlen;
-};
-#else /* NM_IGNORED */
-struct siphash {
-	CSipHash _csiphash;
-};
-
-static inline void
-siphash24_init (struct siphash *state, const uint8_t k[16])
-{
-	c_siphash_init ((CSipHash *) state, k);
-}
-
-static inline void
-siphash24_compress (const void *in, size_t inlen, struct siphash *state)
-{
-	c_siphash_append ((CSipHash *) state, in, inlen);
-}
-
-static inline uint64_t
-siphash24_finalize (struct siphash *state)
-{
-	return c_siphash_finalize ((CSipHash *) state);
-}
-
-static inline uint64_t
-siphash24 (const void *in, size_t inlen, const uint8_t k[16])
-{
-	return c_siphash_hash (k, in, inlen);
-}
-#endif /* NM_IGNORED */
-
-void siphash24_init(struct siphash *state, const uint8_t k[16]);
-void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
-#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state))
-
-uint64_t siphash24_finalize(struct siphash *state);
-
-uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]);
diff --git a/src/systemd/src/basic/socket-util.c b/src/systemd/src/basic/socket-util.c
deleted file mode 100644
index acc22901..00000000
--- a/src/systemd/src/basic/socket-util.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <limits.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <netinet/ip.h>
-#include <poll.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "format-util.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "socket-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
-#include "utf8.h"
-#include "util.h"
-
-#if 0 /* NM_IGNORED */
-#if ENABLE_IDN
-#  define IDN_FLAGS NI_IDN
-#else
-#  define IDN_FLAGS 0
-#endif
-
-static const char* const socket_address_type_table[] = {
-        [SOCK_STREAM] = "Stream",
-        [SOCK_DGRAM] = "Datagram",
-        [SOCK_RAW] = "Raw",
-        [SOCK_RDM] = "ReliableDatagram",
-        [SOCK_SEQPACKET] = "SequentialPacket",
-        [SOCK_DCCP] = "DatagramCongestionControl",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
-
-int socket_address_parse(SocketAddress *a, const char *s) {
-        _cleanup_free_ char *n = NULL;
-        char *e;
-        int r;
-
-        assert(a);
-        assert(s);
-
-        zero(*a);
-        a->type = SOCK_STREAM;
-
-        if (*s == '[') {
-                uint16_t port;
-
-                /* IPv6 in [x:.....:z]:p notation */
-
-                e = strchr(s+1, ']');
-                if (!e)
-                        return -EINVAL;
-
-                n = strndup(s+1, e-s-1);
-                if (!n)
-                        return -ENOMEM;
-
-                errno = 0;
-                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
-                        return errno > 0 ? -errno : -EINVAL;
-
-                e++;
-                if (*e != ':')
-                        return -EINVAL;
-
-                e++;
-                r = parse_ip_port(e, &port);
-                if (r < 0)
-                        return r;
-
-                a->sockaddr.in6.sin6_family = AF_INET6;
-                a->sockaddr.in6.sin6_port = htobe16(port);
-                a->size = sizeof(struct sockaddr_in6);
-
-        } else if (*s == '/') {
-                /* AF_UNIX socket */
-
-                size_t l;
-
-                l = strlen(s);
-                if (l >= sizeof(a->sockaddr.un.sun_path))
-                        return -EINVAL;
-
-                a->sockaddr.un.sun_family = AF_UNIX;
-                memcpy(a->sockaddr.un.sun_path, s, l);
-                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
-
-        } else if (*s == '@') {
-                /* Abstract AF_UNIX socket */
-                size_t l;
-
-                l = strlen(s+1);
-                if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
-                        return -EINVAL;
-
-                a->sockaddr.un.sun_family = AF_UNIX;
-                memcpy(a->sockaddr.un.sun_path+1, s+1, l);
-                a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
-
-        } else if (startswith(s, "vsock:")) {
-                /* AF_VSOCK socket in vsock:cid:port notation */
-                const char *cid_start = s + STRLEN("vsock:");
-                unsigned port;
-
-                e = strchr(cid_start, ':');
-                if (!e)
-                        return -EINVAL;
-
-                r = safe_atou(e+1, &port);
-                if (r < 0)
-                        return r;
-
-                n = strndup(cid_start, e - cid_start);
-                if (!n)
-                        return -ENOMEM;
-
-                if (!isempty(n)) {
-                        r = safe_atou(n, &a->sockaddr.vm.svm_cid);
-                        if (r < 0)
-                                return r;
-                } else
-                        a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
-
-                a->sockaddr.vm.svm_family = AF_VSOCK;
-                a->sockaddr.vm.svm_port = port;
-                a->size = sizeof(struct sockaddr_vm);
-
-        } else {
-                uint16_t port;
-
-                e = strchr(s, ':');
-                if (e) {
-                        r = parse_ip_port(e + 1, &port);
-                        if (r < 0)
-                                return r;
-
-                        n = strndup(s, e-s);
-                        if (!n)
-                                return -ENOMEM;
-
-                        /* IPv4 in w.x.y.z:p notation? */
-                        r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
-                        if (r < 0)
-                                return -errno;
-
-                        if (r > 0) {
-                                /* Gotcha, it's a traditional IPv4 address */
-                                a->sockaddr.in.sin_family = AF_INET;
-                                a->sockaddr.in.sin_port = htobe16(port);
-                                a->size = sizeof(struct sockaddr_in);
-                        } else {
-                                unsigned idx;
-
-                                if (strlen(n) > IF_NAMESIZE-1)
-                                        return -EINVAL;
-
-                                /* Uh, our last resort, an interface name */
-                                idx = if_nametoindex(n);
-                                if (idx == 0)
-                                        return -EINVAL;
-
-                                a->sockaddr.in6.sin6_family = AF_INET6;
-                                a->sockaddr.in6.sin6_port = htobe16(port);
-                                a->sockaddr.in6.sin6_scope_id = idx;
-                                a->sockaddr.in6.sin6_addr = in6addr_any;
-                                a->size = sizeof(struct sockaddr_in6);
-                        }
-                } else {
-
-                        /* Just a port */
-                        r = parse_ip_port(s, &port);
-                        if (r < 0)
-                                return r;
-
-                        if (socket_ipv6_is_supported()) {
-                                a->sockaddr.in6.sin6_family = AF_INET6;
-                                a->sockaddr.in6.sin6_port = htobe16(port);
-                                a->sockaddr.in6.sin6_addr = in6addr_any;
-                                a->size = sizeof(struct sockaddr_in6);
-                        } else {
-                                a->sockaddr.in.sin_family = AF_INET;
-                                a->sockaddr.in.sin_port = htobe16(port);
-                                a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
-                                a->size = sizeof(struct sockaddr_in);
-                        }
-                }
-        }
-
-        return 0;
-}
-
-int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
-        SocketAddress b;
-        int r;
-
-        /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
-
-        r = socket_address_parse(&b, s);
-        if (r < 0)
-                return r;
-
-        if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
-                log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
-                return -EAFNOSUPPORT;
-        }
-
-        *a = b;
-        return 0;
-}
-
-int socket_address_parse_netlink(SocketAddress *a, const char *s) {
-        int family;
-        unsigned group = 0;
-        _cleanup_free_ char *sfamily = NULL;
-        assert(a);
-        assert(s);
-
-        zero(*a);
-        a->type = SOCK_RAW;
-
-        errno = 0;
-        if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
-                return errno > 0 ? -errno : -EINVAL;
-
-        family = netlink_family_from_string(sfamily);
-        if (family < 0)
-                return -EINVAL;
-
-        a->sockaddr.nl.nl_family = AF_NETLINK;
-        a->sockaddr.nl.nl_groups = group;
-
-        a->type = SOCK_RAW;
-        a->size = sizeof(struct sockaddr_nl);
-        a->protocol = family;
-
-        return 0;
-}
-
-int socket_address_verify(const SocketAddress *a) {
-        assert(a);
-
-        switch (socket_address_family(a)) {
-
-        case AF_INET:
-                if (a->size != sizeof(struct sockaddr_in))
-                        return -EINVAL;
-
-                if (a->sockaddr.in.sin_port == 0)
-                        return -EINVAL;
-
-                if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
-                        return -EINVAL;
-
-                return 0;
-
-        case AF_INET6:
-                if (a->size != sizeof(struct sockaddr_in6))
-                        return -EINVAL;
-
-                if (a->sockaddr.in6.sin6_port == 0)
-                        return -EINVAL;
-
-                if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
-                        return -EINVAL;
-
-                return 0;
-
-        case AF_UNIX:
-                if (a->size < offsetof(struct sockaddr_un, sun_path))
-                        return -EINVAL;
-
-                if (a->size > offsetof(struct sockaddr_un, sun_path)) {
-
-                        if (a->sockaddr.un.sun_path[0] != 0) {
-                                char *e;
-
-                                /* path */
-                                e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
-                                if (!e)
-                                        return -EINVAL;
-
-                                if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
-                                        return -EINVAL;
-                        }
-                }
-
-                if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
-                        return -EINVAL;
-
-                return 0;
-
-        case AF_NETLINK:
-
-                if (a->size != sizeof(struct sockaddr_nl))
-                        return -EINVAL;
-
-                if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
-                        return -EINVAL;
-
-                return 0;
-
-        case AF_VSOCK:
-                if (a->size != sizeof(struct sockaddr_vm))
-                        return -EINVAL;
-
-                if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
-                        return -EINVAL;
-
-                return 0;
-
-        default:
-                return -EAFNOSUPPORT;
-        }
-}
-
-int socket_address_print(const SocketAddress *a, char **ret) {
-        int r;
-
-        assert(a);
-        assert(ret);
-
-        r = socket_address_verify(a);
-        if (r < 0)
-                return r;
-
-        if (socket_address_family(a) == AF_NETLINK) {
-                _cleanup_free_ char *sfamily = NULL;
-
-                r = netlink_family_to_string_alloc(a->protocol, &sfamily);
-                if (r < 0)
-                        return r;
-
-                r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
-                if (r < 0)
-                        return -ENOMEM;
-
-                return 0;
-        }
-
-        return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
-}
-
-bool socket_address_can_accept(const SocketAddress *a) {
-        assert(a);
-
-        return
-                IN_SET(a->type, SOCK_STREAM, SOCK_SEQPACKET);
-}
-
-bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
-        assert(a);
-        assert(b);
-
-        /* Invalid addresses are unequal to all */
-        if (socket_address_verify(a) < 0 ||
-            socket_address_verify(b) < 0)
-                return false;
-
-        if (a->type != b->type)
-                return false;
-
-        if (socket_address_family(a) != socket_address_family(b))
-                return false;
-
-        switch (socket_address_family(a)) {
-
-        case AF_INET:
-                if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
-                        return false;
-
-                if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
-                        return false;
-
-                break;
-
-        case AF_INET6:
-                if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
-                        return false;
-
-                if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
-                        return false;
-
-                break;
-
-        case AF_UNIX:
-                if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
-                    b->size <= offsetof(struct sockaddr_un, sun_path))
-                        return false;
-
-                if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
-                        return false;
-
-                if (a->sockaddr.un.sun_path[0]) {
-                        if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
-                                return false;
-                } else {
-                        if (a->size != b->size)
-                                return false;
-
-                        if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
-                                return false;
-                }
-
-                break;
-
-        case AF_NETLINK:
-                if (a->protocol != b->protocol)
-                        return false;
-
-                if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
-                        return false;
-
-                break;
-
-        case AF_VSOCK:
-                if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid)
-                        return false;
-
-                if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port)
-                        return false;
-
-                break;
-
-        default:
-                /* Cannot compare, so we assume the addresses are different */
-                return false;
-        }
-
-        return true;
-}
-
-bool socket_address_is(const SocketAddress *a, const char *s, int type) {
-        struct SocketAddress b;
-
-        assert(a);
-        assert(s);
-
-        if (socket_address_parse(&b, s) < 0)
-                return false;
-
-        b.type = type;
-
-        return socket_address_equal(a, &b);
-}
-
-bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
-        struct SocketAddress b;
-
-        assert(a);
-        assert(s);
-
-        if (socket_address_parse_netlink(&b, s) < 0)
-                return false;
-
-        return socket_address_equal(a, &b);
-}
-
-const char* socket_address_get_path(const SocketAddress *a) {
-        assert(a);
-
-        if (socket_address_family(a) != AF_UNIX)
-                return NULL;
-
-        if (a->sockaddr.un.sun_path[0] == 0)
-                return NULL;
-
-        return a->sockaddr.un.sun_path;
-}
-
-bool socket_ipv6_is_supported(void) {
-        if (access("/proc/net/if_inet6", F_OK) != 0)
-                return false;
-
-        return true;
-}
-
-bool socket_address_matches_fd(const SocketAddress *a, int fd) {
-        SocketAddress b;
-        socklen_t solen;
-
-        assert(a);
-        assert(fd >= 0);
-
-        b.size = sizeof(b.sockaddr);
-        if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
-                return false;
-
-        if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
-                return false;
-
-        solen = sizeof(b.type);
-        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
-                return false;
-
-        if (b.type != a->type)
-                return false;
-
-        if (a->protocol != 0)  {
-                solen = sizeof(b.protocol);
-                if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
-                        return false;
-
-                if (b.protocol != a->protocol)
-                        return false;
-        }
-
-        return socket_address_equal(a, &b);
-}
-
-int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
-        union sockaddr_union *sa = (union sockaddr_union*) _sa;
-
-        /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
-
-        assert(sa);
-
-        switch (sa->sa.sa_family) {
-
-        case AF_INET:
-                *ret_port = be16toh(sa->in.sin_port);
-                return 0;
-
-        case AF_INET6:
-                *ret_port = be16toh(sa->in6.sin6_port);
-                return 0;
-
-        case AF_VSOCK:
-                *ret_port = sa->vm.svm_port;
-                return 0;
-
-        default:
-                return -EAFNOSUPPORT;
-        }
-}
-
-int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
-        union sockaddr_union *sa = (union sockaddr_union*) _sa;
-        char *p;
-        int r;
-
-        assert(sa);
-        assert(salen >= sizeof(sa->sa.sa_family));
-
-        switch (sa->sa.sa_family) {
-
-        case AF_INET: {
-                uint32_t a;
-
-                a = be32toh(sa->in.sin_addr.s_addr);
-
-                if (include_port)
-                        r = asprintf(&p,
-                                     "%u.%u.%u.%u:%u",
-                                     a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
-                                     be16toh(sa->in.sin_port));
-                else
-                        r = asprintf(&p,
-                                     "%u.%u.%u.%u",
-                                     a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
-                if (r < 0)
-                        return -ENOMEM;
-                break;
-        }
-
-        case AF_INET6: {
-                static const unsigned char ipv4_prefix[] = {
-                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
-                };
-
-                if (translate_ipv6 &&
-                    memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
-                        const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
-                        if (include_port)
-                                r = asprintf(&p,
-                                             "%u.%u.%u.%u:%u",
-                                             a[0], a[1], a[2], a[3],
-                                             be16toh(sa->in6.sin6_port));
-                        else
-                                r = asprintf(&p,
-                                             "%u.%u.%u.%u",
-                                             a[0], a[1], a[2], a[3]);
-                        if (r < 0)
-                                return -ENOMEM;
-                } else {
-                        char a[INET6_ADDRSTRLEN];
-
-                        inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
-
-                        if (include_port) {
-                                r = asprintf(&p,
-                                             "[%s]:%u",
-                                             a,
-                                             be16toh(sa->in6.sin6_port));
-                                if (r < 0)
-                                        return -ENOMEM;
-                        } else {
-                                p = strdup(a);
-                                if (!p)
-                                        return -ENOMEM;
-                        }
-                }
-
-                break;
-        }
-
-        case AF_UNIX:
-                if (salen <= offsetof(struct sockaddr_un, sun_path)) {
-                        p = strdup("<unnamed>");
-                        if (!p)
-                                return -ENOMEM;
-
-                } else if (sa->un.sun_path[0] == 0) {
-                        /* abstract */
-
-                        /* FIXME: We assume we can print the
-                         * socket path here and that it hasn't
-                         * more than one NUL byte. That is
-                         * actually an invalid assumption */
-
-                        p = new(char, sizeof(sa->un.sun_path)+1);
-                        if (!p)
-                                return -ENOMEM;
-
-                        p[0] = '@';
-                        memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
-                        p[sizeof(sa->un.sun_path)] = 0;
-
-                } else {
-                        p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
-                        if (!p)
-                                return -ENOMEM;
-                }
-
-                break;
-
-        case AF_VSOCK:
-                if (include_port)
-                        r = asprintf(&p,
-                                     "vsock:%u:%u",
-                                     sa->vm.svm_cid,
-                                     sa->vm.svm_port);
-                else
-                        r = asprintf(&p, "vsock:%u", sa->vm.svm_cid);
-                if (r < 0)
-                        return -ENOMEM;
-                break;
-
-        default:
-                return -EOPNOTSUPP;
-        }
-
-        *ret = p;
-        return 0;
-}
-
-int getpeername_pretty(int fd, bool include_port, char **ret) {
-        union sockaddr_union sa;
-        socklen_t salen = sizeof(sa);
-        int r;
-
-        assert(fd >= 0);
-        assert(ret);
-
-        if (getpeername(fd, &sa.sa, &salen) < 0)
-                return -errno;
-
-        if (sa.sa.sa_family == AF_UNIX) {
-                struct ucred ucred = {};
-
-                /* UNIX connection sockets are anonymous, so let's use
-                 * PID/UID as pretty credentials instead */
-
-                r = getpeercred(fd, &ucred);
-                if (r < 0)
-                        return r;
-
-                if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
-                        return -ENOMEM;
-
-                return 0;
-        }
-
-        /* For remote sockets we translate IPv6 addresses back to IPv4
-         * if applicable, since that's nicer. */
-
-        return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
-}
-
-int getsockname_pretty(int fd, char **ret) {
-        union sockaddr_union sa;
-        socklen_t salen = sizeof(sa);
-
-        assert(fd >= 0);
-        assert(ret);
-
-        if (getsockname(fd, &sa.sa, &salen) < 0)
-                return -errno;
-
-        /* For local sockets we do not translate IPv6 addresses back
-         * to IPv6 if applicable, since this is usually used for
-         * listening sockets where the difference between IPv4 and
-         * IPv6 matters. */
-
-        return sockaddr_pretty(&sa.sa, salen, false, true, ret);
-}
-
-int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
-        int r;
-        char host[NI_MAXHOST], *ret;
-
-        assert(_ret);
-
-        r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
-        if (r != 0) {
-                int saved_errno = errno;
-
-                r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
-                if (r < 0)
-                        return r;
-
-                log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
-        } else {
-                ret = strdup(host);
-                if (!ret)
-                        return -ENOMEM;
-        }
-
-        *_ret = ret;
-        return 0;
-}
-
-int socket_address_unlink(SocketAddress *a) {
-        assert(a);
-
-        if (socket_address_family(a) != AF_UNIX)
-                return 0;
-
-        if (a->sockaddr.un.sun_path[0] == 0)
-                return 0;
-
-        if (unlink(a->sockaddr.un.sun_path) < 0)
-                return -errno;
-
-        return 1;
-}
-
-static const char* const netlink_family_table[] = {
-        [NETLINK_ROUTE] = "route",
-        [NETLINK_FIREWALL] = "firewall",
-        [NETLINK_INET_DIAG] = "inet-diag",
-        [NETLINK_NFLOG] = "nflog",
-        [NETLINK_XFRM] = "xfrm",
-        [NETLINK_SELINUX] = "selinux",
-        [NETLINK_ISCSI] = "iscsi",
-        [NETLINK_AUDIT] = "audit",
-        [NETLINK_FIB_LOOKUP] = "fib-lookup",
-        [NETLINK_CONNECTOR] = "connector",
-        [NETLINK_NETFILTER] = "netfilter",
-        [NETLINK_IP6_FW] = "ip6-fw",
-        [NETLINK_DNRTMSG] = "dnrtmsg",
-        [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
-        [NETLINK_GENERIC] = "generic",
-        [NETLINK_SCSITRANSPORT] = "scsitransport",
-        [NETLINK_ECRYPTFS] = "ecryptfs",
-        [NETLINK_RDMA] = "rdma",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
-
-static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
-        [SOCKET_ADDRESS_DEFAULT] = "default",
-        [SOCKET_ADDRESS_BOTH] = "both",
-        [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
-
-SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) {
-        int r;
-
-        r = parse_boolean(n);
-        if (r > 0)
-                return SOCKET_ADDRESS_IPV6_ONLY;
-        if (r == 0)
-                return SOCKET_ADDRESS_BOTH;
-
-        return socket_address_bind_ipv6_only_from_string(n);
-}
-
-bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
-        assert(a);
-        assert(b);
-
-        if (a->sa.sa_family != b->sa.sa_family)
-                return false;
-
-        if (a->sa.sa_family == AF_INET)
-                return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
-
-        if (a->sa.sa_family == AF_INET6)
-                return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
-
-        if (a->sa.sa_family == AF_VSOCK)
-                return a->vm.svm_cid == b->vm.svm_cid;
-
-        return false;
-}
-
-int fd_inc_sndbuf(int fd, size_t n) {
-        int r, value;
-        socklen_t l = sizeof(value);
-
-        r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
-        if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
-                return 0;
-
-        /* If we have the privileges we will ignore the kernel limit. */
-
-        value = (int) n;
-        if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
-                if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
-                        return -errno;
-
-        return 1;
-}
-
-int fd_inc_rcvbuf(int fd, size_t n) {
-        int r, value;
-        socklen_t l = sizeof(value);
-
-        r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
-        if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
-                return 0;
-
-        /* If we have the privileges we will ignore the kernel limit. */
-
-        value = (int) n;
-        if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
-                if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
-                        return -errno;
-        return 1;
-}
-
-static const char* const ip_tos_table[] = {
-        [IPTOS_LOWDELAY] = "low-delay",
-        [IPTOS_THROUGHPUT] = "throughput",
-        [IPTOS_RELIABILITY] = "reliability",
-        [IPTOS_LOWCOST] = "low-cost",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
-
-bool ifname_valid(const char *p) {
-        bool numeric = true;
-
-        /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
-         * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
-         * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
-
-        if (isempty(p))
-                return false;
-
-        if (strlen(p) >= IFNAMSIZ)
-                return false;
-
-        if (dot_or_dot_dot(p))
-                return false;
-
-        while (*p) {
-                if ((unsigned char) *p >= 127U)
-                        return false;
-
-                if ((unsigned char) *p <= 32U)
-                        return false;
-
-                if (IN_SET(*p, ':', '/'))
-                        return false;
-
-                numeric = numeric && (*p >= '0' && *p <= '9');
-                p++;
-        }
-
-        if (numeric)
-                return false;
-
-        return true;
-}
-
-bool address_label_valid(const char *p) {
-
-        if (isempty(p))
-                return false;
-
-        if (strlen(p) >= IFNAMSIZ)
-                return false;
-
-        while (*p) {
-                if ((uint8_t) *p >= 127U)
-                        return false;
-
-                if ((uint8_t) *p <= 31U)
-                        return false;
-                p++;
-        }
-
-        return true;
-}
-
-int getpeercred(int fd, struct ucred *ucred) {
-        socklen_t n = sizeof(struct ucred);
-        struct ucred u;
-        int r;
-
-        assert(fd >= 0);
-        assert(ucred);
-
-        r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
-        if (r < 0)
-                return -errno;
-
-        if (n != sizeof(struct ucred))
-                return -EIO;
-
-        /* Check if the data is actually useful and not suppressed due to namespacing issues */
-        if (!pid_is_valid(u.pid))
-                return -ENODATA;
-
-        /* Note that we don't check UID/GID here, as namespace translation works differently there: instead of
-         * receiving in "invalid" user/group we get the overflow UID/GID. */
-
-        *ucred = u;
-        return 0;
-}
-
-int getpeersec(int fd, char **ret) {
-        _cleanup_free_ char *s = NULL;
-        socklen_t n = 64;
-
-        assert(fd >= 0);
-        assert(ret);
-
-        for (;;) {
-                s = new0(char, n+1);
-                if (!s)
-                        return -ENOMEM;
-
-                if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0)
-                        break;
-
-                if (errno != ERANGE)
-                        return -errno;
-
-                s = mfree(s);
-        }
-
-        if (isempty(s))
-                return -EOPNOTSUPP;
-
-        *ret = TAKE_PTR(s);
-
-        return 0;
-}
-
-int getpeergroups(int fd, gid_t **ret) {
-        socklen_t n = sizeof(gid_t) * 64;
-        _cleanup_free_ gid_t *d = NULL;
-
-        assert(fd >= 0);
-        assert(ret);
-
-        for (;;) {
-                d = malloc(n);
-                if (!d)
-                        return -ENOMEM;
-
-                if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0)
-                        break;
-
-                if (errno != ERANGE)
-                        return -errno;
-
-                d = mfree(d);
-        }
-
-        assert_se(n % sizeof(gid_t) == 0);
-        n /= sizeof(gid_t);
-
-        if ((socklen_t) (int) n != n)
-                return -E2BIG;
-
-        *ret = TAKE_PTR(d);
-
-        return (int) n;
-}
-
-ssize_t send_one_fd_iov_sa(
-                int transport_fd,
-                int fd,
-                struct iovec *iov, size_t iovlen,
-                const struct sockaddr *sa, socklen_t len,
-                int flags) {
-
-        union {
-                struct cmsghdr cmsghdr;
-                uint8_t buf[CMSG_SPACE(sizeof(int))];
-        } control = {};
-        struct msghdr mh = {
-                .msg_name = (struct sockaddr*) sa,
-                .msg_namelen = len,
-                .msg_iov = iov,
-                .msg_iovlen = iovlen,
-        };
-        ssize_t k;
-
-        assert(transport_fd >= 0);
-
-        /*
-         * We need either an FD or data to send.
-         * If there's nothing, return an error.
-         */
-        if (fd < 0 && !iov)
-                return -EINVAL;
-
-        if (fd >= 0) {
-                struct cmsghdr *cmsg;
-
-                mh.msg_control = &control;
-                mh.msg_controllen = sizeof(control);
-
-                cmsg = CMSG_FIRSTHDR(&mh);
-                cmsg->cmsg_level = SOL_SOCKET;
-                cmsg->cmsg_type = SCM_RIGHTS;
-                cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-                memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
-                mh.msg_controllen = CMSG_SPACE(sizeof(int));
-        }
-        k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags);
-        if (k < 0)
-                return (ssize_t) -errno;
-
-        return k;
-}
-
-int send_one_fd_sa(
-                int transport_fd,
-                int fd,
-                const struct sockaddr *sa, socklen_t len,
-                int flags) {
-
-        assert(fd >= 0);
-
-        return (int) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, sa, len, flags);
-}
-
-ssize_t receive_one_fd_iov(
-                int transport_fd,
-                struct iovec *iov, size_t iovlen,
-                int flags,
-                int *ret_fd) {
-
-        union {
-                struct cmsghdr cmsghdr;
-                uint8_t buf[CMSG_SPACE(sizeof(int))];
-        } control = {};
-        struct msghdr mh = {
-                .msg_control = &control,
-                .msg_controllen = sizeof(control),
-                .msg_iov = iov,
-                .msg_iovlen = iovlen,
-        };
-        struct cmsghdr *cmsg, *found = NULL;
-        ssize_t k;
-
-        assert(transport_fd >= 0);
-        assert(ret_fd);
-
-        /*
-         * Receive a single FD via @transport_fd. We don't care for
-         * the transport-type. We retrieve a single FD at most, so for
-         * packet-based transports, the caller must ensure to send
-         * only a single FD per packet.  This is best used in
-         * combination with send_one_fd().
-         */
-
-        k = recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags);
-        if (k < 0)
-                return (ssize_t) -errno;
-
-        CMSG_FOREACH(cmsg, &mh) {
-                if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SCM_RIGHTS &&
-                    cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
-                        assert(!found);
-                        found = cmsg;
-                        break;
-                }
-        }
-
-        if (!found)
-                cmsg_close_all(&mh);
-
-        /* If didn't receive an FD or any data, return an error. */
-        if (k == 0 && !found)
-                return -EIO;
-
-        if (found)
-                *ret_fd = *(int*) CMSG_DATA(found);
-        else
-                *ret_fd = -1;
-
-        return k;
-}
-
-int receive_one_fd(int transport_fd, int flags) {
-        int fd;
-        ssize_t k;
-
-        k = receive_one_fd_iov(transport_fd, NULL, 0, flags, &fd);
-        if (k == 0)
-                return fd;
-
-        /* k must be negative, since receive_one_fd_iov() only returns
-         * a positive value if data was received through the iov. */
-        assert(k < 0);
-        return (int) k;
-}
-#endif /* NM_IGNORED */
-
-ssize_t next_datagram_size_fd(int fd) {
-        ssize_t l;
-        int k;
-
-        /* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
-         * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
-         * do. This difference is actually of major importance as we need to be sure that the size returned here
-         * actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
-         * the wrong size. */
-
-        l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
-        if (l < 0) {
-                if (IN_SET(errno, EOPNOTSUPP, EFAULT))
-                        goto fallback;
-
-                return -errno;
-        }
-        if (l == 0)
-                goto fallback;
-
-        return l;
-
-fallback:
-        k = 0;
-
-        /* Some sockets (AF_PACKET) do not support null-sized recv() with MSG_TRUNC set, let's fall back to FIONREAD
-         * for them. Checksums don't matter for raw sockets anyway, hence this should be fine. */
-
-        if (ioctl(fd, FIONREAD, &k) < 0)
-                return -errno;
-
-        return (ssize_t) k;
-}
-
-#if 0 /* NM_IGNORED */
-int flush_accept(int fd) {
-
-        struct pollfd pollfd = {
-                .fd = fd,
-                .events = POLLIN,
-        };
-        int r;
-
-        /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
-
-        for (;;) {
-                int cfd;
-
-                r = poll(&pollfd, 1, 0);
-                if (r < 0) {
-                        if (errno == EINTR)
-                                continue;
-
-                        return -errno;
-
-                } else if (r == 0)
-                        return 0;
-
-                cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
-                if (cfd < 0) {
-                        if (errno == EINTR)
-                                continue;
-
-                        if (errno == EAGAIN)
-                                return 0;
-
-                        return -errno;
-                }
-
-                close(cfd);
-        }
-}
-
-struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) {
-        struct cmsghdr *cmsg;
-
-        assert(mh);
-
-        CMSG_FOREACH(cmsg, mh)
-                if (cmsg->cmsg_level == level &&
-                    cmsg->cmsg_type == type &&
-                    (length == (socklen_t) -1 || length == cmsg->cmsg_len))
-                        return cmsg;
-
-        return NULL;
-}
-
-int socket_ioctl_fd(void) {
-        int fd;
-
-        /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
-         * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
-         * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
-         * generic AF_NETLINK. */
-
-        fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
-        if (fd < 0)
-                fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
-        if (fd < 0)
-                return -errno;
-
-        return fd;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/socket-util.h b/src/systemd/src/basic/socket-util.h
deleted file mode 100644
index d7b814ae..00000000
--- a/src/systemd/src/basic/socket-util.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <netinet/ether.h>
-#include <netinet/in.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <linux/netlink.h>
-#include <linux/if_infiniband.h>
-#include <linux/if_packet.h>
-
-#include "macro.h"
-#include "missing.h"
-#include "util.h"
-
-union sockaddr_union {
-        /* The minimal, abstract version */
-        struct sockaddr sa;
-
-        /* The libc provided version that allocates "enough room" for every protocol */
-        struct sockaddr_storage storage;
-
-        /* Protoctol-specific implementations */
-        struct sockaddr_in in;
-        struct sockaddr_in6 in6;
-        struct sockaddr_un un;
-        struct sockaddr_nl nl;
-        struct sockaddr_ll ll;
-#if 0 /* NM_IGNORED */
-        struct sockaddr_vm vm;
-#endif /* NM_IGNORED */
-
-        /* Ensure there is enough space to store Infiniband addresses */
-        uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)];
-
-        /* Ensure there is enough space after the AF_UNIX sun_path for one more NUL byte, just to be sure that the path
-         * component is always followed by at least one NUL byte. */
-        uint8_t un_buffer[sizeof(struct sockaddr_un) + 1];
-};
-
-typedef struct SocketAddress {
-        union sockaddr_union sockaddr;
-
-        /* We store the size here explicitly due to the weird
-         * sockaddr_un semantics for abstract sockets */
-        socklen_t size;
-
-        /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */
-        int type;
-
-        /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
-        int protocol;
-} SocketAddress;
-
-typedef enum SocketAddressBindIPv6Only {
-        SOCKET_ADDRESS_DEFAULT,
-        SOCKET_ADDRESS_BOTH,
-        SOCKET_ADDRESS_IPV6_ONLY,
-        _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX,
-        _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1
-} SocketAddressBindIPv6Only;
-
-#define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
-
-const char* socket_address_type_to_string(int t) _const_;
-int socket_address_type_from_string(const char *s) _pure_;
-
-int socket_address_parse(SocketAddress *a, const char *s);
-int socket_address_parse_and_warn(SocketAddress *a, const char *s);
-int socket_address_parse_netlink(SocketAddress *a, const char *s);
-int socket_address_print(const SocketAddress *a, char **p);
-int socket_address_verify(const SocketAddress *a) _pure_;
-int socket_address_unlink(SocketAddress *a);
-
-bool socket_address_can_accept(const SocketAddress *a) _pure_;
-
-int socket_address_listen(
-                const SocketAddress *a,
-                int flags,
-                int backlog,
-                SocketAddressBindIPv6Only only,
-                const char *bind_to_device,
-                bool reuse_port,
-                bool free_bind,
-                bool transparent,
-                mode_t directory_mode,
-                mode_t socket_mode,
-                const char *label);
-int make_socket_fd(int log_level, const char* address, int type, int flags);
-
-bool socket_address_is(const SocketAddress *a, const char *s, int type);
-bool socket_address_is_netlink(const SocketAddress *a, const char *s);
-
-bool socket_address_matches_fd(const SocketAddress *a, int fd);
-
-bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
-
-const char* socket_address_get_path(const SocketAddress *a);
-
-bool socket_ipv6_is_supported(void);
-
-int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
-
-int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
-int getpeername_pretty(int fd, bool include_port, char **ret);
-int getsockname_pretty(int fd, char **ret);
-
-int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
-
-const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
-SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
-SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *s);
-
-int netlink_family_to_string_alloc(int b, char **s);
-int netlink_family_from_string(const char *s) _pure_;
-
-bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
-
-int fd_inc_sndbuf(int fd, size_t n);
-int fd_inc_rcvbuf(int fd, size_t n);
-
-int ip_tos_to_string_alloc(int i, char **s);
-int ip_tos_from_string(const char *s);
-
-bool ifname_valid(const char *p);
-bool address_label_valid(const char *p);
-
-int getpeercred(int fd, struct ucred *ucred);
-int getpeersec(int fd, char **ret);
-int getpeergroups(int fd, gid_t **ret);
-
-ssize_t send_one_fd_iov_sa(
-                int transport_fd,
-                int fd,
-                struct iovec *iov, size_t iovlen,
-                const struct sockaddr *sa, socklen_t len,
-                int flags);
-int send_one_fd_sa(int transport_fd,
-                   int fd,
-                   const struct sockaddr *sa, socklen_t len,
-                   int flags);
-#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags)
-#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags)
-ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd);
-int receive_one_fd(int transport_fd, int flags);
-
-ssize_t next_datagram_size_fd(int fd);
-
-int flush_accept(int fd);
-
-#define CMSG_FOREACH(cmsg, mh)                                          \
-        for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
-
-struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
-
-/*
- * Certain hardware address types (e.g Infiniband) do not fit into sll_addr
- * (8 bytes) and run over the structure. This macro returns the correct size that
- * must be passed to kernel.
- */
-#define SOCKADDR_LL_LEN(sa)                                             \
-        ({                                                              \
-                const struct sockaddr_ll *_sa = &(sa);                  \
-                size_t _mac_len = sizeof(_sa->sll_addr);                \
-                assert(_sa->sll_family == AF_PACKET);                   \
-                if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER)           \
-                        _mac_len = MAX(_mac_len, (size_t) ETH_ALEN);    \
-                if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND)      \
-                        _mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
-                offsetof(struct sockaddr_ll, sll_addr) + _mac_len;      \
-        })
-
-/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
-#define SOCKADDR_UN_LEN(sa)                                             \
-        ({                                                              \
-                const struct sockaddr_un *_sa = &(sa);                  \
-                assert(_sa->sun_family == AF_UNIX);                     \
-                offsetof(struct sockaddr_un, sun_path) +                \
-                        (_sa->sun_path[0] == 0 ?                        \
-                         1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
-                         strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
-        })
-
-int socket_ioctl_fd(void);
diff --git a/src/systemd/src/basic/sparse-endian.h b/src/systemd/src/basic/sparse-endian.h
deleted file mode 100644
index 5e59de54..00000000
--- a/src/systemd/src/basic/sparse-endian.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* SPDX-License-Identifier: MIT
- *
- * Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-#ifndef SPARSE_ENDIAN_H
-#define SPARSE_ENDIAN_H
-
-#include <byteswap.h>
-#include <endian.h>
-#include <stdint.h>
-
-#ifdef __CHECKER__
-#define __sd_bitwise __attribute__((bitwise))
-#define __sd_force __attribute__((force))
-#else
-#define __sd_bitwise
-#define __sd_force
-#endif
-
-typedef uint16_t __sd_bitwise le16_t;
-typedef uint16_t __sd_bitwise be16_t;
-typedef uint32_t __sd_bitwise le32_t;
-typedef uint32_t __sd_bitwise be32_t;
-typedef uint64_t __sd_bitwise le64_t;
-typedef uint64_t __sd_bitwise be64_t;
-
-#undef htobe16
-#undef htole16
-#undef be16toh
-#undef le16toh
-#undef htobe32
-#undef htole32
-#undef be32toh
-#undef le32toh
-#undef htobe64
-#undef htole64
-#undef be64toh
-#undef le64toh
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define bswap_16_on_le(x) __bswap_16(x)
-#define bswap_32_on_le(x) __bswap_32(x)
-#define bswap_64_on_le(x) __bswap_64(x)
-#define bswap_16_on_be(x) (x)
-#define bswap_32_on_be(x) (x)
-#define bswap_64_on_be(x) (x)
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define bswap_16_on_le(x) (x)
-#define bswap_32_on_le(x) (x)
-#define bswap_64_on_le(x) (x)
-#define bswap_16_on_be(x) __bswap_16(x)
-#define bswap_32_on_be(x) __bswap_32(x)
-#define bswap_64_on_be(x) __bswap_64(x)
-#endif
-
-static inline le16_t htole16(uint16_t value) { return (le16_t __sd_force) bswap_16_on_be(value); }
-static inline le32_t htole32(uint32_t value) { return (le32_t __sd_force) bswap_32_on_be(value); }
-static inline le64_t htole64(uint64_t value) { return (le64_t __sd_force) bswap_64_on_be(value); }
-
-static inline be16_t htobe16(uint16_t value) { return (be16_t __sd_force) bswap_16_on_le(value); }
-static inline be32_t htobe32(uint32_t value) { return (be32_t __sd_force) bswap_32_on_le(value); }
-static inline be64_t htobe64(uint64_t value) { return (be64_t __sd_force) bswap_64_on_le(value); }
-
-static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __sd_force)value); }
-static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __sd_force)value); }
-static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __sd_force)value); }
-
-static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __sd_force)value); }
-static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __sd_force)value); }
-static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __sd_force)value); }
-
-#undef __sd_bitwise
-#undef __sd_force
-
-#endif /* SPARSE_ENDIAN_H */
diff --git a/src/systemd/src/basic/stat-util.c b/src/systemd/src/basic/stat-util.c
deleted file mode 100644
index d645ce30..00000000
--- a/src/systemd/src/basic/stat-util.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/magic.h>
-#include <sched.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fs-util.h"
-#include "macro.h"
-#include "missing.h"
-#include "stat-util.h"
-#include "string-util.h"
-
-#if 0 /* NM_IGNORED */
-int is_symlink(const char *path) {
-        struct stat info;
-
-        assert(path);
-
-        if (lstat(path, &info) < 0)
-                return -errno;
-
-        return !!S_ISLNK(info.st_mode);
-}
-
-int is_dir(const char* path, bool follow) {
-        struct stat st;
-        int r;
-
-        assert(path);
-
-        if (follow)
-                r = stat(path, &st);
-        else
-                r = lstat(path, &st);
-        if (r < 0)
-                return -errno;
-
-        return !!S_ISDIR(st.st_mode);
-}
-
-int is_dir_fd(int fd) {
-        struct stat st;
-        int r;
-
-        r = fstat(fd, &st);
-        if (r < 0)
-                return -errno;
-
-        return !!S_ISDIR(st.st_mode);
-}
-
-int is_device_node(const char *path) {
-        struct stat info;
-
-        assert(path);
-
-        if (lstat(path, &info) < 0)
-                return -errno;
-
-        return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
-}
-
-int dir_is_empty(const char *path) {
-        _cleanup_closedir_ DIR *d;
-        struct dirent *de;
-
-        d = opendir(path);
-        if (!d)
-                return -errno;
-
-        FOREACH_DIRENT(de, d, return -errno)
-                return 0;
-
-        return 1;
-}
-
-bool null_or_empty(struct stat *st) {
-        assert(st);
-
-        if (S_ISREG(st->st_mode) && st->st_size <= 0)
-                return true;
-
-        /* We don't want to hardcode the major/minor of /dev/null,
-         * hence we do a simpler "is this a device node?" check. */
-
-        if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
-                return true;
-
-        return false;
-}
-
-int null_or_empty_path(const char *fn) {
-        struct stat st;
-
-        assert(fn);
-
-        if (stat(fn, &st) < 0)
-                return -errno;
-
-        return null_or_empty(&st);
-}
-
-int null_or_empty_fd(int fd) {
-        struct stat st;
-
-        assert(fd >= 0);
-
-        if (fstat(fd, &st) < 0)
-                return -errno;
-
-        return null_or_empty(&st);
-}
-
-int path_is_read_only_fs(const char *path) {
-        struct statvfs st;
-
-        assert(path);
-
-        if (statvfs(path, &st) < 0)
-                return -errno;
-
-        if (st.f_flag & ST_RDONLY)
-                return true;
-
-        /* On NFS, statvfs() might not reflect whether we can actually
-         * write to the remote share. Let's try again with
-         * access(W_OK) which is more reliable, at least sometimes. */
-        if (access(path, W_OK) < 0 && errno == EROFS)
-                return true;
-
-        return false;
-}
-
-int files_same(const char *filea, const char *fileb, int flags) {
-        struct stat a, b;
-
-        assert(filea);
-        assert(fileb);
-
-        if (fstatat(AT_FDCWD, filea, &a, flags) < 0)
-                return -errno;
-
-        if (fstatat(AT_FDCWD, fileb, &b, flags) < 0)
-                return -errno;
-
-        return a.st_dev == b.st_dev &&
-               a.st_ino == b.st_ino;
-}
-
-bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
-        assert(s);
-        assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
-
-        return F_TYPE_EQUAL(s->f_type, magic_value);
-}
-
-int fd_is_fs_type(int fd, statfs_f_type_t magic_value) {
-        struct statfs s;
-
-        if (fstatfs(fd, &s) < 0)
-                return -errno;
-
-        return is_fs_type(&s, magic_value);
-}
-
-int path_is_fs_type(const char *path, statfs_f_type_t magic_value) {
-        _cleanup_close_ int fd = -1;
-
-        fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
-        if (fd < 0)
-                return -errno;
-
-        return fd_is_fs_type(fd, magic_value);
-}
-
-bool is_temporary_fs(const struct statfs *s) {
-        return is_fs_type(s, TMPFS_MAGIC) ||
-                is_fs_type(s, RAMFS_MAGIC);
-}
-
-bool is_network_fs(const struct statfs *s) {
-        return is_fs_type(s, CIFS_MAGIC_NUMBER) ||
-                is_fs_type(s, CODA_SUPER_MAGIC) ||
-                is_fs_type(s, NCP_SUPER_MAGIC) ||
-                is_fs_type(s, NFS_SUPER_MAGIC) ||
-                is_fs_type(s, SMB_SUPER_MAGIC) ||
-                is_fs_type(s, V9FS_MAGIC) ||
-                is_fs_type(s, AFS_SUPER_MAGIC) ||
-                is_fs_type(s, OCFS2_SUPER_MAGIC);
-}
-
-int fd_is_temporary_fs(int fd) {
-        struct statfs s;
-
-        if (fstatfs(fd, &s) < 0)
-                return -errno;
-
-        return is_temporary_fs(&s);
-}
-
-int fd_is_network_fs(int fd) {
-        struct statfs s;
-
-        if (fstatfs(fd, &s) < 0)
-                return -errno;
-
-        return is_network_fs(&s);
-}
-
-int fd_is_network_ns(int fd) {
-        int r;
-
-        r = fd_is_fs_type(fd, NSFS_MAGIC);
-        if (r <= 0)
-                return r;
-
-        r = ioctl(fd, NS_GET_NSTYPE);
-        if (r < 0)
-                return -errno;
-
-        return r == CLONE_NEWNET;
-}
-
-int path_is_temporary_fs(const char *path) {
-        _cleanup_close_ int fd = -1;
-
-        fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
-        if (fd < 0)
-                return -errno;
-
-        return fd_is_temporary_fs(fd);
-}
-#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);
-}
diff --git a/src/systemd/src/basic/stat-util.h b/src/systemd/src/basic/stat-util.h
deleted file mode 100644
index 1a725f1d..00000000
--- a/src/systemd/src/basic/stat-util.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/types.h>
-#include <sys/vfs.h>
-
-#include "macro.h"
-
-int is_symlink(const char *path);
-int is_dir(const char *path, bool follow);
-int is_dir_fd(int fd);
-int is_device_node(const char *path);
-
-int dir_is_empty(const char *path);
-
-static inline int dir_is_populated(const char *path) {
-        int r;
-        r = dir_is_empty(path);
-        if (r < 0)
-                return r;
-        return !r;
-}
-
-bool null_or_empty(struct stat *st) _pure_;
-int null_or_empty_path(const char *fn);
-int null_or_empty_fd(int fd);
-
-int path_is_read_only_fs(const char *path);
-
-int files_same(const char *filea, const char *fileb, int flags);
-
-/* The .f_type field of struct statfs is really weird defined on
- * different archs. Let's give its type a name. */
-typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t;
-
-bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
-int fd_is_fs_type(int fd, statfs_f_type_t magic_value);
-int path_is_fs_type(const char *path, statfs_f_type_t magic_value);
-
-bool is_temporary_fs(const struct statfs *s) _pure_;
-bool is_network_fs(const struct statfs *s) _pure_;
-
-int fd_is_temporary_fs(int fd);
-int fd_is_network_fs(int fd);
-
-int fd_is_network_ns(int fd);
-
-int path_is_temporary_fs(const char *path);
-
-/* Because statfs.t_type can be int on some architectures, we have to cast
- * the const magic to the type, otherwise the compiler warns about
- * signed/unsigned comparison, because the magic can be 32 bit unsigned.
- */
-#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
-
-int stat_verify_regular(const struct stat *st);
-int fd_verify_regular(int fd);
diff --git a/src/systemd/src/basic/stdio-util.h b/src/systemd/src/basic/stdio-util.h
deleted file mode 100644
index 73c03274..00000000
--- a/src/systemd/src/basic/stdio-util.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <printf.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "macro.h"
-
-#define snprintf_ok(buf, len, fmt, ...) \
-        ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
-
-#define xsprintf(buf, fmt, ...) \
-        assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
-
-#define VA_FORMAT_ADVANCE(format, ap)                                   \
-do {                                                                    \
-        int _argtypes[128];                                             \
-        size_t _i, _k;                                                  \
-        _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
-        assert(_k < ELEMENTSOF(_argtypes));                             \
-        for (_i = 0; _i < _k; _i++) {                                   \
-                if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
-                        (void) va_arg(ap, void*);                       \
-                        continue;                                       \
-                }                                                       \
-                                                                        \
-                switch (_argtypes[_i]) {                                \
-                case PA_INT:                                            \
-                case PA_INT|PA_FLAG_SHORT:                              \
-                case PA_CHAR:                                           \
-                        (void) va_arg(ap, int);                         \
-                        break;                                          \
-                case PA_INT|PA_FLAG_LONG:                               \
-                        (void) va_arg(ap, long int);                    \
-                        break;                                          \
-                case PA_INT|PA_FLAG_LONG_LONG:                          \
-                        (void) va_arg(ap, long long int);               \
-                        break;                                          \
-                case PA_WCHAR:                                          \
-                        (void) va_arg(ap, wchar_t);                     \
-                        break;                                          \
-                case PA_WSTRING:                                        \
-                case PA_STRING:                                         \
-                case PA_POINTER:                                        \
-                        (void) va_arg(ap, void*);                       \
-                        break;                                          \
-                case PA_FLOAT:                                          \
-                case PA_DOUBLE:                                         \
-                        (void) va_arg(ap, double);                      \
-                        break;                                          \
-                case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
-                        (void) va_arg(ap, long double);                 \
-                        break;                                          \
-                default:                                                \
-                        assert_not_reached("Unknown format string argument."); \
-                }                                                       \
-        }                                                               \
-} while (false)
diff --git a/src/systemd/src/basic/string-table.c b/src/systemd/src/basic/string-table.c
deleted file mode 100644
index 94412ed2..00000000
--- a/src/systemd/src/basic/string-table.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include "string-table.h"
-#include "string-util.h"
-
-ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
-        size_t i;
-
-        if (!key)
-                return -1;
-
-        for (i = 0; i < len; ++i)
-                if (streq_ptr(table[i], key))
-                        return (ssize_t) i;
-
-        return -1;
-}
diff --git a/src/systemd/src/basic/string-table.h b/src/systemd/src/basic/string-table.h
deleted file mode 100644
index 9bd78793..00000000
--- a/src/systemd/src/basic/string-table.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#pragma once
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "macro.h"
-#include "parse-util.h"
-#include "string-util.h"
-
-ssize_t string_table_lookup(const char * const *table, size_t len, const char *key);
-
-/* For basic lookup tables with strictly enumerated entries */
-#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
-        scope const char *name##_to_string(type i) {                    \
-                if (i < 0 || i >= (type) ELEMENTSOF(name##_table))      \
-                        return NULL;                                    \
-                return name##_table[i];                                 \
-        }
-
-#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)        \
-        scope type name##_from_string(const char *s) {                  \
-                return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
-        }
-
-#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
-        scope type name##_from_string(const char *s) {                  \
-                int b;                                                  \
-                if (!s)                                                 \
-                        return -1;                                      \
-                b = parse_boolean(s);                                   \
-                if (b == 0)                                             \
-                        return (type) 0;                                \
-                else if (b > 0)                                         \
-                        return yes;                                     \
-                return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
-        }
-
-#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \
-        scope int name##_to_string_alloc(type i, char **str) {          \
-                char *s;                                                \
-                if (i < 0 || i > max)                                   \
-                        return -ERANGE;                                 \
-                if (i < (type) ELEMENTSOF(name##_table)) {              \
-                        s = strdup(name##_table[i]);                    \
-                        if (!s)                                         \
-                                return -ENOMEM;                         \
-                } else {                                                \
-                        if (asprintf(&s, "%i", i) < 0)                  \
-                                return -ENOMEM;                         \
-                }                                                       \
-                *str = s;                                               \
-                return 0;                                               \
-        }
-
-#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \
-        type name##_from_string(const char *s) {                        \
-                type i;                                                 \
-                unsigned u = 0;                                         \
-                if (!s)                                                 \
-                        return (type) -1;                               \
-                for (i = 0; i < (type) ELEMENTSOF(name##_table); i++)   \
-                        if (streq_ptr(name##_table[i], s))              \
-                                return i;                               \
-                if (safe_atou(s, &u) >= 0 && u <= max)                  \
-                        return (type) u;                                \
-                return (type) -1;                                       \
-        }                                                               \
-
-#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope)                    \
-        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
-        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)
-
-#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope)   \
-        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
-        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope)
-
-#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
-
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
-
-/* For string conversions where numbers are also acceptable */
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max)         \
-        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,)  \
-        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,)
-
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \
-        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \
-        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static)
-
-#define DUMP_STRING_TABLE(name,type,max)                                \
-        do {                                                            \
-                type _k;                                                \
-                flockfile(stdout);                                      \
-                for (_k = 0; _k < (max); _k++) {                        \
-                        const char *_t;                                 \
-                        _t = name##_to_string(_k);                      \
-                        if (!_t)                                        \
-                                continue;                               \
-                        fputs_unlocked(_t, stdout);                     \
-                        fputc_unlocked('\n', stdout);                   \
-                }                                                       \
-                funlockfile(stdout);                                    \
-        } while(false)
diff --git a/src/systemd/src/basic/string-util.c b/src/systemd/src/basic/string-util.c
deleted file mode 100644
index 1747f35b..00000000
--- a/src/systemd/src/basic/string-util.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "escape.h"
-#include "gunicode.h"
-#include "locale-util.h"
-#include "macro.h"
-#include "string-util.h"
-#include "terminal-util.h"
-#include "utf8.h"
-#include "util.h"
-#include "fileio.h"
-
-int strcmp_ptr(const char *a, const char *b) {
-
-        /* Like strcmp(), but tries to make sense of NULL pointers */
-        if (a && b)
-                return strcmp(a, b);
-
-        if (!a && b)
-                return -1;
-
-        if (a && !b)
-                return 1;
-
-        return 0;
-}
-
-char* endswith(const char *s, const char *postfix) {
-        size_t sl, pl;
-
-        assert(s);
-        assert(postfix);
-
-        sl = strlen(s);
-        pl = strlen(postfix);
-
-        if (pl == 0)
-                return (char*) s + sl;
-
-        if (sl < pl)
-                return NULL;
-
-        if (memcmp(s + sl - pl, postfix, pl) != 0)
-                return NULL;
-
-        return (char*) s + sl - pl;
-}
-
-char* endswith_no_case(const char *s, const char *postfix) {
-        size_t sl, pl;
-
-        assert(s);
-        assert(postfix);
-
-        sl = strlen(s);
-        pl = strlen(postfix);
-
-        if (pl == 0)
-                return (char*) s + sl;
-
-        if (sl < pl)
-                return NULL;
-
-        if (strcasecmp(s + sl - pl, postfix) != 0)
-                return NULL;
-
-        return (char*) s + sl - pl;
-}
-
-char* first_word(const char *s, const char *word) {
-        size_t sl, wl;
-        const char *p;
-
-        assert(s);
-        assert(word);
-
-        /* Checks if the string starts with the specified word, either
-         * followed by NUL or by whitespace. Returns a pointer to the
-         * NUL or the first character after the whitespace. */
-
-        sl = strlen(s);
-        wl = strlen(word);
-
-        if (sl < wl)
-                return NULL;
-
-        if (wl == 0)
-                return (char*) s;
-
-        if (memcmp(s, word, wl) != 0)
-                return NULL;
-
-        p = s + wl;
-        if (*p == 0)
-                return (char*) p;
-
-        if (!strchr(WHITESPACE, *p))
-                return NULL;
-
-        p += strspn(p, WHITESPACE);
-        return (char*) p;
-}
-
-static size_t strcspn_escaped(const char *s, const char *reject) {
-        bool escaped = false;
-        int n;
-
-        for (n=0; s[n]; n++) {
-                if (escaped)
-                        escaped = false;
-                else if (s[n] == '\\')
-                        escaped = true;
-                else if (strchr(reject, s[n]))
-                        break;
-        }
-
-        /* if s ends in \, return index of previous char */
-        return n - escaped;
-}
-
-/* Split a string into words. */
-const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
-        const char *current;
-
-        current = *state;
-
-        if (!*current) {
-                assert(**state == '\0');
-                return NULL;
-        }
-
-        current += strspn(current, separator);
-        if (!*current) {
-                *state = current;
-                return NULL;
-        }
-
-        if (quoted && strchr("\'\"", *current)) {
-                char quotechars[2] = {*current, '\0'};
-
-                *l = strcspn_escaped(current + 1, quotechars);
-                if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
-                    (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
-                        /* right quote missing or garbage at the end */
-                        *state = current;
-                        return NULL;
-                }
-                *state = current++ + *l + 2;
-        } else if (quoted) {
-                *l = strcspn_escaped(current, separator);
-                if (current[*l] && !strchr(separator, current[*l])) {
-                        /* unfinished escape */
-                        *state = current;
-                        return NULL;
-                }
-                *state = current + *l;
-        } else {
-                *l = strcspn(current, separator);
-                *state = current + *l;
-        }
-
-        return current;
-}
-
-char *strnappend(const char *s, const char *suffix, size_t b) {
-        size_t a;
-        char *r;
-
-        if (!s && !suffix)
-                return strdup("");
-
-        if (!s)
-                return strndup(suffix, b);
-
-        if (!suffix)
-                return strdup(s);
-
-        assert(s);
-        assert(suffix);
-
-        a = strlen(s);
-        if (b > ((size_t) -1) - a)
-                return NULL;
-
-        r = new(char, a+b+1);
-        if (!r)
-                return NULL;
-
-        memcpy(r, s, a);
-        memcpy(r+a, suffix, b);
-        r[a+b] = 0;
-
-        return r;
-}
-
-char *strappend(const char *s, const char *suffix) {
-        return strnappend(s, suffix, strlen_ptr(suffix));
-}
-
-#if 0 /* NM_IGNORED */
-char *strjoin_real(const char *x, ...) {
-        va_list ap;
-        size_t l;
-        char *r, *p;
-
-        va_start(ap, x);
-
-        if (x) {
-                l = strlen(x);
-
-                for (;;) {
-                        const char *t;
-                        size_t n;
-
-                        t = va_arg(ap, const char *);
-                        if (!t)
-                                break;
-
-                        n = strlen(t);
-                        if (n > ((size_t) -1) - l) {
-                                va_end(ap);
-                                return NULL;
-                        }
-
-                        l += n;
-                }
-        } else
-                l = 0;
-
-        va_end(ap);
-
-        r = new(char, l+1);
-        if (!r)
-                return NULL;
-
-        if (x) {
-                p = stpcpy(r, x);
-
-                va_start(ap, x);
-
-                for (;;) {
-                        const char *t;
-
-                        t = va_arg(ap, const char *);
-                        if (!t)
-                                break;
-
-                        p = stpcpy(p, t);
-                }
-
-                va_end(ap);
-        } else
-                r[0] = 0;
-
-        return r;
-}
-
-char *strstrip(char *s) {
-        if (!s)
-                return NULL;
-
-        /* Drops trailing whitespace. Modifies the string in place. Returns pointer to first non-space character */
-
-        return delete_trailing_chars(skip_leading_chars(s, WHITESPACE), WHITESPACE);
-}
-
-char *delete_chars(char *s, const char *bad) {
-        char *f, *t;
-
-        /* Drops all specified bad characters, regardless where in the string */
-
-        if (!s)
-                return NULL;
-
-        if (!bad)
-                bad = WHITESPACE;
-
-        for (f = s, t = s; *f; f++) {
-                if (strchr(bad, *f))
-                        continue;
-
-                *(t++) = *f;
-        }
-
-        *t = 0;
-
-        return s;
-}
-
-char *delete_trailing_chars(char *s, const char *bad) {
-        char *p, *c = s;
-
-        /* Drops all specified bad characters, at the end of the string */
-
-        if (!s)
-                return NULL;
-
-        if (!bad)
-                bad = WHITESPACE;
-
-        for (p = s; *p; p++)
-                if (!strchr(bad, *p))
-                        c = p + 1;
-
-        *c = 0;
-
-        return s;
-}
-#endif /* NM_IGNORED */
-
-char *truncate_nl(char *s) {
-        assert(s);
-
-        s[strcspn(s, NEWLINE)] = 0;
-        return s;
-}
-
-char ascii_tolower(char x) {
-
-        if (x >= 'A' && x <= 'Z')
-                return x - 'A' + 'a';
-
-        return x;
-}
-
-char ascii_toupper(char x) {
-
-        if (x >= 'a' && x <= 'z')
-                return x - 'a' + 'A';
-
-        return x;
-}
-
-char *ascii_strlower(char *t) {
-        char *p;
-
-        assert(t);
-
-        for (p = t; *p; p++)
-                *p = ascii_tolower(*p);
-
-        return t;
-}
-
-char *ascii_strupper(char *t) {
-        char *p;
-
-        assert(t);
-
-        for (p = t; *p; p++)
-                *p = ascii_toupper(*p);
-
-        return t;
-}
-
-char *ascii_strlower_n(char *t, size_t n) {
-        size_t i;
-
-        if (n <= 0)
-                return t;
-
-        for (i = 0; i < n; i++)
-                t[i] = ascii_tolower(t[i]);
-
-        return t;
-}
-
-int ascii_strcasecmp_n(const char *a, const char *b, size_t n) {
-
-        for (; n > 0; a++, b++, n--) {
-                int x, y;
-
-                x = (int) (uint8_t) ascii_tolower(*a);
-                y = (int) (uint8_t) ascii_tolower(*b);
-
-                if (x != y)
-                        return x - y;
-        }
-
-        return 0;
-}
-
-int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m) {
-        int r;
-
-        r = ascii_strcasecmp_n(a, b, MIN(n, m));
-        if (r != 0)
-                return r;
-
-        if (n < m)
-                return -1;
-        else if (n > m)
-                return 1;
-        else
-                return 0;
-}
-
-bool chars_intersect(const char *a, const char *b) {
-        const char *p;
-
-        /* Returns true if any of the chars in a are in b. */
-        for (p = a; *p; p++)
-                if (strchr(b, *p))
-                        return true;
-
-        return false;
-}
-
-bool string_has_cc(const char *p, const char *ok) {
-        const char *t;
-
-        assert(p);
-
-        /*
-         * Check if a string contains control characters. If 'ok' is
-         * non-NULL it may be a string containing additional CCs to be
-         * considered OK.
-         */
-
-        for (t = p; *t; t++) {
-                if (ok && strchr(ok, *t))
-                        continue;
-
-                if (*t > 0 && *t < ' ')
-                        return true;
-
-                if (*t == 127)
-                        return true;
-        }
-
-        return false;
-}
-
-#if 0 /* NM_IGNORED */
-static int write_ellipsis(char *buf, bool unicode) {
-        if (unicode || is_locale_utf8()) {
-                buf[0] = 0xe2; /* tri-dot ellipsis: … */
-                buf[1] = 0x80;
-                buf[2] = 0xa6;
-        } else {
-                buf[0] = '.';
-                buf[1] = '.';
-                buf[2] = '.';
-        }
-
-        return 3;
-}
-
-static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
-        size_t x, need_space, suffix_len;
-        char *t;
-
-        assert(s);
-        assert(percent <= 100);
-        assert(new_length != (size_t) -1);
-
-        if (old_length <= new_length)
-                return strndup(s, old_length);
-
-        /* Special case short ellipsations */
-        switch (new_length) {
-
-        case 0:
-                return strdup("");
-
-        case 1:
-                if (is_locale_utf8())
-                        return strdup("…");
-                else
-                        return strdup(".");
-
-        case 2:
-                if (!is_locale_utf8())
-                        return strdup("..");
-
-                break;
-
-        default:
-                break;
-        }
-
-        /* Calculate how much space the ellipsis will take up. If we are in UTF-8 mode we only need space for one
-         * character ("…"), otherwise for three characters ("..."). Note that in both cases we need 3 bytes of storage,
-         * either for the UTF-8 encoded character or for three ASCII characters. */
-        need_space = is_locale_utf8() ? 1 : 3;
-
-        t = new(char, new_length+3);
-        if (!t)
-                return NULL;
-
-        assert(new_length >= need_space);
-
-        x = ((new_length - need_space) * percent + 50) / 100;
-        assert(x <= new_length - need_space);
-
-        memcpy(t, s, x);
-        write_ellipsis(t + x, false);
-        suffix_len = new_length - x - need_space;
-        memcpy(t + x + 3, s + old_length - suffix_len, suffix_len);
-        *(t + x + 3 + suffix_len) = '\0';
-
-        return t;
-}
-
-char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
-        size_t x, k, len, len2;
-        const char *i, *j;
-        char *e;
-        int r;
-
-        /* Note that 'old_length' refers to bytes in the string, while 'new_length' refers to character cells taken up
-         * on screen. This distinction doesn't matter for ASCII strings, but it does matter for non-ASCII UTF-8
-         * strings.
-         *
-         * Ellipsation is done in a locale-dependent way:
-         * 1. If the string passed in is fully ASCII and the current locale is not UTF-8, three dots are used ("...")
-         * 2. Otherwise, a unicode ellipsis is used ("…")
-         *
-         * In other words: you'll get a unicode ellipsis as soon as either the string contains non-ASCII characters or
-         * the current locale is UTF-8.
-         */
-
-        assert(s);
-        assert(percent <= 100);
-
-        if (new_length == (size_t) -1)
-                return strndup(s, old_length);
-
-        if (new_length == 0)
-                return strdup("");
-
-        /* If no multibyte characters use ascii_ellipsize_mem for speed */
-        if (ascii_is_valid_n(s, old_length))
-                return ascii_ellipsize_mem(s, old_length, new_length, percent);
-
-        x = ((new_length - 1) * percent) / 100;
-        assert(x <= new_length - 1);
-
-        k = 0;
-        for (i = s; i < s + old_length; i = utf8_next_char(i)) {
-                char32_t c;
-                int w;
-
-                r = utf8_encoded_to_unichar(i, &c);
-                if (r < 0)
-                        return NULL;
-
-                w = unichar_iswide(c) ? 2 : 1;
-                if (k + w <= x)
-                        k += w;
-                else
-                        break;
-        }
-
-        for (j = s + old_length; j > i; ) {
-                char32_t c;
-                int w;
-                const char *jj;
-
-                jj = utf8_prev_char(j);
-                r = utf8_encoded_to_unichar(jj, &c);
-                if (r < 0)
-                        return NULL;
-
-                w = unichar_iswide(c) ? 2 : 1;
-                if (k + w <= new_length) {
-                        k += w;
-                        j = jj;
-                } else
-                        break;
-        }
-        assert(i <= j);
-
-        /* we don't actually need to ellipsize */
-        if (i == j)
-                return memdup_suffix0(s, old_length);
-
-        /* make space for ellipsis, if possible */
-        if (j < s + old_length)
-                j = utf8_next_char(j);
-        else if (i > s)
-                i = utf8_prev_char(i);
-
-        len = i - s;
-        len2 = s + old_length - j;
-        e = new(char, len + 3 + len2 + 1);
-        if (!e)
-                return NULL;
-
-        /*
-        printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
-               old_length, new_length, x, len, len2, k);
-        */
-
-        memcpy(e, s, len);
-        write_ellipsis(e + len, true);
-        memcpy(e + len + 3, j, len2);
-        *(e + len + 3 + len2) = '\0';
-
-        return e;
-}
-
-char *cellescape(char *buf, size_t len, const char *s) {
-        /* Escape and ellipsize s into buffer buf of size len. Only non-control ASCII
-         * characters are copied as they are, everything else is escaped. The result
-         * is different then if escaping and ellipsization was performed in two
-         * separate steps, because each sequence is either stored in full or skipped.
-         *
-         * This function should be used for logging about strings which expected to
-         * be plain ASCII in a safe way.
-         *
-         * An ellipsis will be used if s is too long. It was always placed at the
-         * very end.
-         */
-
-        size_t i = 0, last_char_width[4] = {}, k = 0, j;
-
-        assert(len > 0); /* at least a terminating NUL */
-
-        for (;;) {
-                char four[4];
-                int w;
-
-                if (*s == 0) /* terminating NUL detected? then we are done! */
-                        goto done;
-
-                w = cescape_char(*s, four);
-                if (i + w + 1 > len) /* This character doesn't fit into the buffer anymore? In that case let's
-                                      * ellipsize at the previous location */
-                        break;
-
-                /* OK, there was space, let's add this escaped character to the buffer */
-                memcpy(buf + i, four, w);
-                i += w;
-
-                /* And remember its width in the ring buffer */
-                last_char_width[k] = w;
-                k = (k + 1) % 4;
-
-                s++;
-        }
-
-        /* Ellipsation is necessary. This means we might need to truncate the string again to make space for 4
-         * characters ideally, but the buffer is shorter than that in the first place take what we can get */
-        for (j = 0; j < ELEMENTSOF(last_char_width); j++) {
-
-                if (i + 4 <= len) /* nice, we reached our space goal */
-                        break;
-
-                k = k == 0 ? 3 : k - 1;
-                if (last_char_width[k] == 0) /* bummer, we reached the beginning of the strings */
-                        break;
-
-                assert(i >= last_char_width[k]);
-                i -= last_char_width[k];
-        }
-
-        if (i + 4 <= len) /* yay, enough space */
-                i += write_ellipsis(buf + i, false);
-        else if (i + 3 <= len) { /* only space for ".." */
-                buf[i++] = '.';
-                buf[i++] = '.';
-        } else if (i + 2 <= len) /* only space for a single "." */
-                buf[i++] = '.';
-        else
-                assert(i + 1 <= len);
-
- done:
-        buf[i] = '\0';
-        return buf;
-}
-#endif /* NM_IGNORED */
-
-bool nulstr_contains(const char *nulstr, const char *needle) {
-        const char *i;
-
-        if (!nulstr)
-                return false;
-
-        NULSTR_FOREACH(i, nulstr)
-                if (streq(i, needle))
-                        return true;
-
-        return false;
-}
-
-char* strshorten(char *s, size_t l) {
-        assert(s);
-
-        if (strnlen(s, l+1) > l)
-                s[l] = 0;
-
-        return s;
-}
-
-char *strreplace(const char *text, const char *old_string, const char *new_string) {
-        size_t l, old_len, new_len, allocated = 0;
-        char *t, *ret = NULL;
-        const char *f;
-
-        assert(old_string);
-        assert(new_string);
-
-        if (!text)
-                return NULL;
-
-        old_len = strlen(old_string);
-        new_len = strlen(new_string);
-
-        l = strlen(text);
-        if (!GREEDY_REALLOC(ret, allocated, l+1))
-                return NULL;
-
-        f = text;
-        t = ret;
-        while (*f) {
-                size_t d, nl;
-
-                if (!startswith(f, old_string)) {
-                        *(t++) = *(f++);
-                        continue;
-                }
-
-                d = t - ret;
-                nl = l - old_len + new_len;
-
-                if (!GREEDY_REALLOC(ret, allocated, nl + 1))
-                        return mfree(ret);
-
-                l = nl;
-                t = ret + d;
-
-                t = stpcpy(t, new_string);
-                f += old_len;
-        }
-
-        *t = 0;
-        return ret;
-}
-
-static void advance_offsets(ssize_t diff, size_t offsets[2], size_t shift[2], size_t size) {
-        if (!offsets)
-                return;
-
-        if ((size_t) diff < offsets[0])
-                shift[0] += size;
-        if ((size_t) diff < offsets[1])
-                shift[1] += size;
-}
-
-char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
-        const char *i, *begin = NULL;
-        enum {
-                STATE_OTHER,
-                STATE_ESCAPE,
-                STATE_CSI,
-                STATE_CSO,
-        } state = STATE_OTHER;
-        char *obuf = NULL;
-        size_t osz = 0, isz, shift[2] = {};
-        FILE *f;
-
-        assert(ibuf);
-        assert(*ibuf);
-
-        /* This does three things:
-         *
-         * 1. Replaces TABs by 8 spaces
-         * 2. Strips ANSI color sequences (a subset of CSI), i.e. ESC '[' … 'm' sequences
-         * 3. Strips ANSI operating system sequences (CSO), i.e. ESC ']' … BEL sequences
-         *
-         * Everything else will be left as it is. In particular other ANSI sequences are left as they are, as are any
-         * other special characters. Truncated ANSI sequences are left-as is too. This call is supposed to suppress the
-         * most basic formatting noise, but nothing else.
-         *
-         * Why care for CSO sequences? Well, to undo what terminal_urlify() and friends generate. */
-
-        isz = _isz ? *_isz : strlen(*ibuf);
-
-        f = open_memstream(&obuf, &osz);
-        if (!f)
-                return NULL;
-
-        /* Note we turn off internal locking on f for performance reasons.  It's safe to do so since we created f here
-         * and it doesn't leave our scope. */
-
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
-        for (i = *ibuf; i < *ibuf + isz + 1; i++) {
-
-                switch (state) {
-
-                case STATE_OTHER:
-                        if (i >= *ibuf + isz) /* EOT */
-                                break;
-                        else if (*i == '\x1B')
-                                state = STATE_ESCAPE;
-                        else if (*i == '\t') {
-                                fputs("        ", f);
-                                advance_offsets(i - *ibuf, highlight, shift, 7);
-                        } else
-                                fputc(*i, f);
-
-                        break;
-
-                case STATE_ESCAPE:
-                        if (i >= *ibuf + isz) { /* EOT */
-                                fputc('\x1B', f);
-                                advance_offsets(i - *ibuf, highlight, shift, 1);
-                                break;
-                        } else if (*i == '[') { /* ANSI CSI */
-                                state = STATE_CSI;
-                                begin = i + 1;
-                        } else if (*i == ']') { /* ANSI CSO */
-                                state = STATE_CSO;
-                                begin = i + 1;
-                        } else {
-                                fputc('\x1B', f);
-                                fputc(*i, f);
-                                advance_offsets(i - *ibuf, highlight, shift, 1);
-                                state = STATE_OTHER;
-                        }
-
-                        break;
-
-                case STATE_CSI:
-
-                        if (i >= *ibuf + isz || /* EOT … */
-                            !strchr("01234567890;m", *i)) { /* … or invalid chars in sequence */
-                                fputc('\x1B', f);
-                                fputc('[', f);
-                                advance_offsets(i - *ibuf, highlight, shift, 2);
-                                state = STATE_OTHER;
-                                i = begin-1;
-                        } else if (*i == 'm')
-                                state = STATE_OTHER;
-
-                        break;
-
-                case STATE_CSO:
-
-                        if (i >= *ibuf + isz || /* EOT … */
-                            (*i != '\a' && (uint8_t) *i < 32U) || (uint8_t) *i > 126U) { /* … or invalid chars in sequence */
-                                fputc('\x1B', f);
-                                fputc(']', f);
-                                advance_offsets(i - *ibuf, highlight, shift, 2);
-                                state = STATE_OTHER;
-                                i = begin-1;
-                        } else if (*i == '\a')
-                                state = STATE_OTHER;
-
-                        break;
-                }
-        }
-
-        if (fflush_and_check(f) < 0) {
-                fclose(f);
-                return mfree(obuf);
-        }
-
-        fclose(f);
-
-        free(*ibuf);
-        *ibuf = obuf;
-
-        if (_isz)
-                *_isz = osz;
-
-        if (highlight) {
-                highlight[0] += shift[0];
-                highlight[1] += shift[1];
-        }
-
-        return obuf;
-}
-
-#if 0 /* NM_IGNORED */
-char *strextend_with_separator(char **x, const char *separator, ...) {
-        bool need_separator;
-        size_t f, l, l_separator;
-        char *r, *p;
-        va_list ap;
-
-        assert(x);
-
-        l = f = strlen_ptr(*x);
-
-        need_separator = !isempty(*x);
-        l_separator = strlen_ptr(separator);
-
-        va_start(ap, separator);
-        for (;;) {
-                const char *t;
-                size_t n;
-
-                t = va_arg(ap, const char *);
-                if (!t)
-                        break;
-
-                n = strlen(t);
-
-                if (need_separator)
-                        n += l_separator;
-
-                if (n > ((size_t) -1) - l) {
-                        va_end(ap);
-                        return NULL;
-                }
-
-                l += n;
-                need_separator = true;
-        }
-        va_end(ap);
-
-        need_separator = !isempty(*x);
-
-        r = realloc(*x, l+1);
-        if (!r)
-                return NULL;
-
-        p = r + f;
-
-        va_start(ap, separator);
-        for (;;) {
-                const char *t;
-
-                t = va_arg(ap, const char *);
-                if (!t)
-                        break;
-
-                if (need_separator && separator)
-                        p = stpcpy(p, separator);
-
-                p = stpcpy(p, t);
-
-                need_separator = true;
-        }
-        va_end(ap);
-
-        assert(p == r + l);
-
-        *p = 0;
-        *x = r;
-
-        return r + l;
-}
-#endif /* NM_IGNORED */
-
-char *strrep(const char *s, unsigned n) {
-        size_t l;
-        char *r, *p;
-        unsigned i;
-
-        assert(s);
-
-        l = strlen(s);
-        p = r = malloc(l * n + 1);
-        if (!r)
-                return NULL;
-
-        for (i = 0; i < n; i++)
-                p = stpcpy(p, s);
-
-        *p = 0;
-        return r;
-}
-
-int split_pair(const char *s, const char *sep, char **l, char **r) {
-        char *x, *a, *b;
-
-        assert(s);
-        assert(sep);
-        assert(l);
-        assert(r);
-
-        if (isempty(sep))
-                return -EINVAL;
-
-        x = strstr(s, sep);
-        if (!x)
-                return -EINVAL;
-
-        a = strndup(s, x - s);
-        if (!a)
-                return -ENOMEM;
-
-        b = strdup(x + strlen(sep));
-        if (!b) {
-                free(a);
-                return -ENOMEM;
-        }
-
-        *l = a;
-        *r = b;
-
-        return 0;
-}
-
-int free_and_strdup(char **p, const char *s) {
-        char *t;
-
-        assert(p);
-
-        /* Replaces a string pointer with an strdup()ed new string,
-         * possibly freeing the old one. */
-
-        if (streq_ptr(*p, s))
-                return 0;
-
-        if (s) {
-                t = strdup(s);
-                if (!t)
-                        return -ENOMEM;
-        } else
-                t = NULL;
-
-        free(*p);
-        *p = t;
-
-        return 1;
-}
-
-#if !HAVE_EXPLICIT_BZERO
-/*
- * Pointer to memset is volatile so that compiler must de-reference
- * the pointer and can't assume that it points to any function in
- * particular (such as memset, which it then might further "optimize")
- * This approach is inspired by openssl's crypto/mem_clr.c.
- */
-typedef void *(*memset_t)(void *,int,size_t);
-
-static volatile memset_t memset_func = memset;
-
-void explicit_bzero(void *p, size_t l) {
-        memset_func(p, '\0', l);
-}
-#endif
-
-char* string_erase(char *x) {
-        if (!x)
-                return NULL;
-
-        /* A delicious drop of snake-oil! To be called on memory where
-         * we stored passphrases or so, after we used them. */
-        explicit_bzero(x, strlen(x));
-        return x;
-}
-
-char *string_free_erase(char *s) {
-        return mfree(string_erase(s));
-}
-
-bool string_is_safe(const char *p) {
-        const char *t;
-
-        if (!p)
-                return false;
-
-        for (t = p; *t; t++) {
-                if (*t > 0 && *t < ' ') /* no control characters */
-                        return false;
-
-                if (strchr(QUOTES "\\\x7f", *t))
-                        return false;
-        }
-
-        return true;
-}
diff --git a/src/systemd/src/basic/string-util.h b/src/systemd/src/basic/string-util.h
deleted file mode 100644
index c0cc4e78..00000000
--- a/src/systemd/src/basic/string-util.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <alloca.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "macro.h"
-
-/* What is interpreted as whitespace? */
-#define WHITESPACE        " \t\n\r"
-#define NEWLINE           "\n\r"
-#define QUOTES            "\"\'"
-#define COMMENTS          "#;"
-#define GLOB_CHARS        "*?["
-#define DIGITS            "0123456789"
-#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
-#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-#define LETTERS           LOWERCASE_LETTERS UPPERCASE_LETTERS
-#define ALPHANUMERICAL    LETTERS DIGITS
-#define HEXDIGITS         DIGITS "abcdefABCDEF"
-
-#define streq(a,b) (strcmp((a),(b)) == 0)
-#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
-#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
-#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
-
-int strcmp_ptr(const char *a, const char *b) _pure_;
-
-static inline bool streq_ptr(const char *a, const char *b) {
-        return strcmp_ptr(a, b) == 0;
-}
-
-static inline const char* strempty(const char *s) {
-        return s ?: "";
-}
-
-static inline const char* strnull(const char *s) {
-        return s ?: "(null)";
-}
-
-static inline const char *strna(const char *s) {
-        return s ?: "n/a";
-}
-
-static inline bool isempty(const char *p) {
-        return !p || !p[0];
-}
-
-static inline const char *empty_to_null(const char *p) {
-        return isempty(p) ? NULL : p;
-}
-
-static inline const char *empty_to_dash(const char *str) {
-        return isempty(str) ? "-" : str;
-}
-
-static inline char *startswith(const char *s, const char *prefix) {
-        size_t l;
-
-        l = strlen(prefix);
-        if (strncmp(s, prefix, l) == 0)
-                return (char*) s + l;
-
-        return NULL;
-}
-
-static inline char *startswith_no_case(const char *s, const char *prefix) {
-        size_t l;
-
-        l = strlen(prefix);
-        if (strncasecmp(s, prefix, l) == 0)
-                return (char*) s + l;
-
-        return NULL;
-}
-
-char *endswith(const char *s, const char *postfix) _pure_;
-char *endswith_no_case(const char *s, const char *postfix) _pure_;
-
-char *first_word(const char *s, const char *word) _pure_;
-
-const char* split(const char **state, size_t *l, const char *separator, bool quoted);
-
-#define FOREACH_WORD(word, length, s, state)                            \
-        _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
-
-#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state)       \
-        _FOREACH_WORD(word, length, s, separator, false, state)
-
-#define _FOREACH_WORD(word, length, s, separator, quoted, state)        \
-        for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
-
-char *strappend(const char *s, const char *suffix);
-char *strnappend(const char *s, const char *suffix, size_t length);
-
-char *strjoin_real(const char *x, ...) _sentinel_;
-#define strjoin(a, ...) strjoin_real((a), __VA_ARGS__, NULL)
-
-#define strjoina(a, ...)                                                \
-        ({                                                              \
-                const char *_appendees_[] = { a, __VA_ARGS__ };         \
-                char *_d_, *_p_;                                        \
-                size_t _len_ = 0;                                          \
-                size_t _i_;                                           \
-                for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
-                        _len_ += strlen(_appendees_[_i_]);              \
-                _p_ = _d_ = alloca(_len_ + 1);                          \
-                for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
-                        _p_ = stpcpy(_p_, _appendees_[_i_]);            \
-                *_p_ = 0;                                               \
-                _d_;                                                    \
-        })
-
-char *strstrip(char *s);
-char *delete_chars(char *s, const char *bad);
-char *delete_trailing_chars(char *s, const char *bad);
-char *truncate_nl(char *s);
-
-static inline char *skip_leading_chars(const char *s, const char *bad) {
-
-        if (!s)
-                return NULL;
-
-        if (!bad)
-                bad = WHITESPACE;
-
-        return (char*) s + strspn(s, bad);
-}
-
-char ascii_tolower(char x);
-char *ascii_strlower(char *s);
-char *ascii_strlower_n(char *s, size_t n);
-
-char ascii_toupper(char x);
-char *ascii_strupper(char *s);
-
-int ascii_strcasecmp_n(const char *a, const char *b, size_t n);
-int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m);
-
-bool chars_intersect(const char *a, const char *b) _pure_;
-
-static inline bool _pure_ in_charset(const char *s, const char* charset) {
-        assert(s);
-        assert(charset);
-        return s[strspn(s, charset)] == '\0';
-}
-
-bool string_has_cc(const char *p, const char *ok) _pure_;
-
-char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
-static inline char *ellipsize(const char *s, size_t length, unsigned percent) {
-        return ellipsize_mem(s, strlen(s), length, percent);
-}
-
-char *cellescape(char *buf, size_t len, const char *s);
-
-/* This limit is arbitrary, enough to give some idea what the string contains */
-#define CELLESCAPE_DEFAULT_LENGTH 64
-
-bool nulstr_contains(const char *nulstr, const char *needle);
-
-char* strshorten(char *s, size_t l);
-
-char *strreplace(const char *text, const char *old_string, const char *new_string);
-
-char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]);
-
-char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_;
-
-#define strextend(x, ...) strextend_with_separator(x, NULL, __VA_ARGS__)
-
-char *strrep(const char *s, unsigned n);
-
-int split_pair(const char *s, const char *sep, char **l, char **r);
-
-int free_and_strdup(char **p, const char *s);
-
-/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
-static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
-
-        if (needlelen <= 0)
-                return (void*) haystack;
-
-        if (haystacklen < needlelen)
-                return NULL;
-
-        assert(haystack);
-        assert(needle);
-
-        return memmem(haystack, haystacklen, needle, needlelen);
-}
-
-#if !HAVE_EXPLICIT_BZERO
-void explicit_bzero(void *p, size_t l);
-#endif
-
-char *string_erase(char *x);
-
-char *string_free_erase(char *s);
-DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
-#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
-
-bool string_is_safe(const char *p) _pure_;
-
-static inline size_t strlen_ptr(const char *s) {
-        if (!s)
-                return 0;
-
-        return strlen(s);
-}
-
-/* Like startswith(), but operates on arbitrary memory blocks */
-static inline void *memory_startswith(const void *p, size_t sz, const char *token) {
-        size_t n;
-
-        assert(token);
-
-        n = strlen(token);
-        if (sz < n)
-                return NULL;
-
-        assert(p);
-
-        if (memcmp(p, token, n) != 0)
-                return NULL;
-
-        return (uint8_t*) p + n;
-}
diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c
deleted file mode 100644
index 6f80b317..00000000
--- a/src/systemd/src/basic/strv.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <fnmatch.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "escape.h"
-#include "extract-word.h"
-#include "fileio.h"
-#include "string-util.h"
-#include "strv.h"
-#include "util.h"
-
-char *strv_find(char **l, const char *name) {
-        char **i;
-
-        assert(name);
-
-        STRV_FOREACH(i, l)
-                if (streq(*i, name))
-                        return *i;
-
-        return NULL;
-}
-
-char *strv_find_prefix(char **l, const char *name) {
-        char **i;
-
-        assert(name);
-
-        STRV_FOREACH(i, l)
-                if (startswith(*i, name))
-                        return *i;
-
-        return NULL;
-}
-
-char *strv_find_startswith(char **l, const char *name) {
-        char **i, *e;
-
-        assert(name);
-
-        /* Like strv_find_prefix, but actually returns only the
-         * suffix, not the whole item */
-
-        STRV_FOREACH(i, l) {
-                e = startswith(*i, name);
-                if (e)
-                        return e;
-        }
-
-        return NULL;
-}
-
-void strv_clear(char **l) {
-        char **k;
-
-        if (!l)
-                return;
-
-        for (k = l; *k; k++)
-                free(*k);
-
-        *l = NULL;
-}
-
-char **strv_free(char **l) {
-        strv_clear(l);
-        return mfree(l);
-}
-
-char **strv_free_erase(char **l) {
-        char **i;
-
-        STRV_FOREACH(i, l)
-                string_erase(*i);
-
-        return strv_free(l);
-}
-
-char **strv_copy(char * const *l) {
-        char **r, **k;
-
-        k = r = new(char*, strv_length(l) + 1);
-        if (!r)
-                return NULL;
-
-        if (l)
-                for (; *l; k++, l++) {
-                        *k = strdup(*l);
-                        if (!*k) {
-                                strv_free(r);
-                                return NULL;
-                        }
-                }
-
-        *k = NULL;
-        return r;
-}
-
-size_t strv_length(char * const *l) {
-        size_t n = 0;
-
-        if (!l)
-                return 0;
-
-        for (; *l; l++)
-                n++;
-
-        return n;
-}
-
-char **strv_new_ap(const char *x, va_list ap) {
-        const char *s;
-        _cleanup_strv_free_ char **a = NULL;
-        size_t n = 0, i = 0;
-        va_list aq;
-
-        /* As a special trick we ignore all listed strings that equal
-         * STRV_IGNORE. This is supposed to be used with the
-         * STRV_IFNOTNULL() macro to include possibly NULL strings in
-         * the string list. */
-
-        if (x) {
-                n = x == STRV_IGNORE ? 0 : 1;
-
-                va_copy(aq, ap);
-                while ((s = va_arg(aq, const char*))) {
-                        if (s == STRV_IGNORE)
-                                continue;
-
-                        n++;
-                }
-
-                va_end(aq);
-        }
-
-        a = new(char*, n+1);
-        if (!a)
-                return NULL;
-
-        if (x) {
-                if (x != STRV_IGNORE) {
-                        a[i] = strdup(x);
-                        if (!a[i])
-                                return NULL;
-                        i++;
-                }
-
-                while ((s = va_arg(ap, const char*))) {
-
-                        if (s == STRV_IGNORE)
-                                continue;
-
-                        a[i] = strdup(s);
-                        if (!a[i])
-                                return NULL;
-
-                        i++;
-                }
-        }
-
-        a[i] = NULL;
-
-        return TAKE_PTR(a);
-}
-
-char **strv_new(const char *x, ...) {
-        char **r;
-        va_list ap;
-
-        va_start(ap, x);
-        r = strv_new_ap(x, ap);
-        va_end(ap);
-
-        return r;
-}
-
-int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
-        char **s, **t;
-        size_t p, q, i = 0, j;
-
-        assert(a);
-
-        if (strv_isempty(b))
-                return 0;
-
-        p = strv_length(*a);
-        q = strv_length(b);
-
-        t = reallocarray(*a, p + q + 1, sizeof(char *));
-        if (!t)
-                return -ENOMEM;
-
-        t[p] = NULL;
-        *a = t;
-
-        STRV_FOREACH(s, b) {
-
-                if (filter_duplicates && strv_contains(t, *s))
-                        continue;
-
-                t[p+i] = strdup(*s);
-                if (!t[p+i])
-                        goto rollback;
-
-                i++;
-                t[p+i] = NULL;
-        }
-
-        assert(i <= q);
-
-        return (int) i;
-
-rollback:
-        for (j = 0; j < i; j++)
-                free(t[p + j]);
-
-        t[p] = NULL;
-        return -ENOMEM;
-}
-
-int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
-        int r;
-        char **s;
-
-        STRV_FOREACH(s, b) {
-                char *v;
-
-                v = strappend(*s, suffix);
-                if (!v)
-                        return -ENOMEM;
-
-                r = strv_push(a, v);
-                if (r < 0) {
-                        free(v);
-                        return r;
-                }
-        }
-
-        return 0;
-}
-
-char **strv_split(const char *s, const char *separator) {
-        const char *word, *state;
-        size_t l;
-        size_t n, i;
-        char **r;
-
-        assert(s);
-
-        s += strspn(s, separator);
-        if (isempty(s))
-                return new0(char*, 1);
-
-        n = 0;
-        FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
-                n++;
-
-        r = new(char*, n+1);
-        if (!r)
-                return NULL;
-
-        i = 0;
-        FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
-                r[i] = strndup(word, l);
-                if (!r[i]) {
-                        strv_free(r);
-                        return NULL;
-                }
-
-                i++;
-        }
-
-        r[i] = NULL;
-        return r;
-}
-
-char **strv_split_newlines(const char *s) {
-        char **l;
-        size_t n;
-
-        assert(s);
-
-        /* Special version of strv_split() that splits on newlines and
-         * suppresses an empty string at the end */
-
-        l = strv_split(s, NEWLINE);
-        if (!l)
-                return NULL;
-
-        n = strv_length(l);
-        if (n <= 0)
-                return l;
-
-        if (isempty(l[n - 1]))
-                l[n - 1] = mfree(l[n - 1]);
-
-        return l;
-}
-
-#if 0 /* NM_IGNORED */
-int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
-        _cleanup_strv_free_ char **l = NULL;
-        size_t n = 0, allocated = 0;
-        int r;
-
-        assert(t);
-        assert(s);
-
-        for (;;) {
-                _cleanup_free_ char *word = NULL;
-
-                r = extract_first_word(&s, &word, separators, flags);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        break;
-
-                if (!GREEDY_REALLOC(l, allocated, n + 2))
-                        return -ENOMEM;
-
-                l[n++] = TAKE_PTR(word);
-
-                l[n] = NULL;
-        }
-
-        if (!l) {
-                l = new0(char*, 1);
-                if (!l)
-                        return -ENOMEM;
-        }
-
-        *t = TAKE_PTR(l);
-
-        return (int) n;
-}
-#endif /* NM_IGNORED */
-
-char *strv_join(char **l, const char *separator) {
-        char *r, *e;
-        char **s;
-        size_t n, k;
-
-        if (!separator)
-                separator = " ";
-
-        k = strlen(separator);
-
-        n = 0;
-        STRV_FOREACH(s, l) {
-                if (s != l)
-                        n += k;
-                n += strlen(*s);
-        }
-
-        r = new(char, n+1);
-        if (!r)
-                return NULL;
-
-        e = r;
-        STRV_FOREACH(s, l) {
-                if (s != l)
-                        e = stpcpy(e, separator);
-
-                e = stpcpy(e, *s);
-        }
-
-        *e = 0;
-
-        return r;
-}
-
-int strv_push(char ***l, char *value) {
-        char **c;
-        size_t n, m;
-
-        if (!value)
-                return 0;
-
-        n = strv_length(*l);
-
-        /* Increase and check for overflow */
-        m = n + 2;
-        if (m < n)
-                return -ENOMEM;
-
-        c = reallocarray(*l, m, sizeof(char*));
-        if (!c)
-                return -ENOMEM;
-
-        c[n] = value;
-        c[n+1] = NULL;
-
-        *l = c;
-        return 0;
-}
-
-int strv_push_pair(char ***l, char *a, char *b) {
-        char **c;
-        size_t n, m;
-
-        if (!a && !b)
-                return 0;
-
-        n = strv_length(*l);
-
-        /* increase and check for overflow */
-        m = n + !!a + !!b + 1;
-        if (m < n)
-                return -ENOMEM;
-
-        c = reallocarray(*l, m, sizeof(char*));
-        if (!c)
-                return -ENOMEM;
-
-        if (a)
-                c[n++] = a;
-        if (b)
-                c[n++] = b;
-        c[n] = NULL;
-
-        *l = c;
-        return 0;
-}
-
-int strv_insert(char ***l, size_t position, char *value) {
-        char **c;
-        size_t n, m, i;
-
-        if (!value)
-                return 0;
-
-        n = strv_length(*l);
-        position = MIN(position, n);
-
-        /* increase and check for overflow */
-        m = n + 2;
-        if (m < n)
-                return -ENOMEM;
-
-        c = new(char*, m);
-        if (!c)
-                return -ENOMEM;
-
-        for (i = 0; i < position; i++)
-                c[i] = (*l)[i];
-        c[position] = value;
-        for (i = position; i < n; i++)
-                c[i+1] = (*l)[i];
-
-        c[n+1] = NULL;
-
-        free(*l);
-        *l = c;
-
-        return 0;
-}
-
-int strv_consume(char ***l, char *value) {
-        int r;
-
-        r = strv_push(l, value);
-        if (r < 0)
-                free(value);
-
-        return r;
-}
-
-int strv_consume_pair(char ***l, char *a, char *b) {
-        int r;
-
-        r = strv_push_pair(l, a, b);
-        if (r < 0) {
-                free(a);
-                free(b);
-        }
-
-        return r;
-}
-
-int strv_consume_prepend(char ***l, char *value) {
-        int r;
-
-        r = strv_push_prepend(l, value);
-        if (r < 0)
-                free(value);
-
-        return r;
-}
-
-int strv_extend(char ***l, const char *value) {
-        char *v;
-
-        if (!value)
-                return 0;
-
-        v = strdup(value);
-        if (!v)
-                return -ENOMEM;
-
-        return strv_consume(l, v);
-}
-
-int strv_extend_front(char ***l, const char *value) {
-        size_t n, m;
-        char *v, **c;
-
-        assert(l);
-
-        /* Like strv_extend(), but prepends rather than appends the new entry */
-
-        if (!value)
-                return 0;
-
-        n = strv_length(*l);
-
-        /* Increase and overflow check. */
-        m = n + 2;
-        if (m < n)
-                return -ENOMEM;
-
-        v = strdup(value);
-        if (!v)
-                return -ENOMEM;
-
-        c = reallocarray(*l, m, sizeof(char*));
-        if (!c) {
-                free(v);
-                return -ENOMEM;
-        }
-
-        memmove(c+1, c, n * sizeof(char*));
-        c[0] = v;
-        c[n+1] = NULL;
-
-        *l = c;
-        return 0;
-}
-
-char **strv_uniq(char **l) {
-        char **i;
-
-        /* Drops duplicate entries. The first identical string will be
-         * kept, the others dropped */
-
-        STRV_FOREACH(i, l)
-                strv_remove(i+1, *i);
-
-        return l;
-}
-
-bool strv_is_uniq(char **l) {
-        char **i;
-
-        STRV_FOREACH(i, l)
-                if (strv_find(i+1, *i))
-                        return false;
-
-        return true;
-}
-
-char **strv_remove(char **l, const char *s) {
-        char **f, **t;
-
-        if (!l)
-                return NULL;
-
-        assert(s);
-
-        /* Drops every occurrence of s in the string list, edits
-         * in-place. */
-
-        for (f = t = l; *f; f++)
-                if (streq(*f, s))
-                        free(*f);
-                else
-                        *(t++) = *f;
-
-        *t = NULL;
-        return l;
-}
-
-char **strv_parse_nulstr(const char *s, size_t l) {
-        /* l is the length of the input data, which will be split at NULs into
-         * elements of the resulting strv. Hence, the number of items in the resulting strv
-         * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
-         * unless s[l-1] is NUL, in which case the final empty string is not stored in
-         * the resulting strv, and length is equal to the number of NUL bytes.
-         *
-         * Note that contrary to a normal nulstr which cannot contain empty strings, because
-         * the input data is terminated by any two consequent NUL bytes, this parser accepts
-         * empty strings in s.
-         */
-
-        const char *p;
-        size_t c = 0, i = 0;
-        char **v;
-
-        assert(s || l <= 0);
-
-        if (l <= 0)
-                return new0(char*, 1);
-
-        for (p = s; p < s + l; p++)
-                if (*p == 0)
-                        c++;
-
-        if (s[l-1] != 0)
-                c++;
-
-        v = new0(char*, c+1);
-        if (!v)
-                return NULL;
-
-        p = s;
-        while (p < s + l) {
-                const char *e;
-
-                e = memchr(p, 0, s + l - p);
-
-                v[i] = strndup(p, e ? e - p : s + l - p);
-                if (!v[i]) {
-                        strv_free(v);
-                        return NULL;
-                }
-
-                i++;
-
-                if (!e)
-                        break;
-
-                p = e + 1;
-        }
-
-        assert(i == c);
-
-        return v;
-}
-
-char **strv_split_nulstr(const char *s) {
-        const char *i;
-        char **r = NULL;
-
-        NULSTR_FOREACH(i, s)
-                if (strv_extend(&r, i) < 0) {
-                        strv_free(r);
-                        return NULL;
-                }
-
-        if (!r)
-                return strv_new(NULL, NULL);
-
-        return r;
-}
-
-int strv_make_nulstr(char **l, char **p, size_t *q) {
-        /* A valid nulstr with two NULs at the end will be created, but
-         * q will be the length without the two trailing NULs. Thus the output
-         * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
-         * and can also be parsed by strv_parse_nulstr as long as the length
-         * is provided separately.
-         */
-
-        size_t n_allocated = 0, n = 0;
-        _cleanup_free_ char *m = NULL;
-        char **i;
-
-        assert(p);
-        assert(q);
-
-        STRV_FOREACH(i, l) {
-                size_t z;
-
-                z = strlen(*i);
-
-                if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
-                        return -ENOMEM;
-
-                memcpy(m + n, *i, z + 1);
-                n += z + 1;
-        }
-
-        if (!m) {
-                m = new0(char, 1);
-                if (!m)
-                        return -ENOMEM;
-                n = 1;
-        } else
-                /* make sure there is a second extra NUL at the end of resulting nulstr */
-                m[n] = '\0';
-
-        assert(n > 0);
-        *p = m;
-        *q = n - 1;
-
-        m = NULL;
-
-        return 0;
-}
-
-bool strv_overlap(char **a, char **b) {
-        char **i;
-
-        STRV_FOREACH(i, a)
-                if (strv_contains(b, *i))
-                        return true;
-
-        return false;
-}
-
-static int str_compare(const void *_a, const void *_b) {
-        const char **a = (const char**) _a, **b = (const char**) _b;
-
-        return strcmp(*a, *b);
-}
-
-char **strv_sort(char **l) {
-        qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
-        return l;
-}
-
-bool strv_equal(char **a, char **b) {
-
-        if (strv_isempty(a))
-                return strv_isempty(b);
-
-        if (strv_isempty(b))
-                return false;
-
-        for ( ; *a || *b; ++a, ++b)
-                if (!streq_ptr(*a, *b))
-                        return false;
-
-        return true;
-}
-
-void strv_print(char **l) {
-        char **s;
-
-        STRV_FOREACH(s, l)
-                puts(*s);
-}
-
-int strv_extendf(char ***l, const char *format, ...) {
-        va_list ap;
-        char *x;
-        int r;
-
-        va_start(ap, format);
-        r = vasprintf(&x, format, ap);
-        va_end(ap);
-
-        if (r < 0)
-                return -ENOMEM;
-
-        return strv_consume(l, x);
-}
-
-char **strv_reverse(char **l) {
-        size_t n, i;
-
-        n = strv_length(l);
-        if (n <= 1)
-                return l;
-
-        for (i = 0; i < n / 2; i++)
-                SWAP_TWO(l[i], l[n-1-i]);
-
-        return l;
-}
-
-char **strv_shell_escape(char **l, const char *bad) {
-        char **s;
-
-        /* Escapes every character in every string in l that is in bad,
-         * edits in-place, does not roll-back on error. */
-
-        STRV_FOREACH(s, l) {
-                char *v;
-
-                v = shell_escape(*s, bad);
-                if (!v)
-                        return NULL;
-
-                free(*s);
-                *s = v;
-        }
-
-        return l;
-}
-
-bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
-        char* const* p;
-
-        STRV_FOREACH(p, patterns)
-                if (fnmatch(*p, s, flags) == 0)
-                        return true;
-
-        return false;
-}
-
-char ***strv_free_free(char ***l) {
-        char ***i;
-
-        if (!l)
-                return NULL;
-
-        for (i = l; *i; i++)
-                strv_free(*i);
-
-        return mfree(l);
-}
-
-char **strv_skip(char **l, size_t n) {
-
-        while (n > 0) {
-                if (strv_isempty(l))
-                        return l;
-
-                l++, n--;
-        }
-
-        return l;
-}
-
-int strv_extend_n(char ***l, const char *value, size_t n) {
-        size_t i, j, k;
-        char **nl;
-
-        assert(l);
-
-        if (!value)
-                return 0;
-        if (n == 0)
-                return 0;
-
-        /* Adds the value n times to l */
-
-        k = strv_length(*l);
-
-        nl = reallocarray(*l, k + n + 1, sizeof(char *));
-        if (!nl)
-                return -ENOMEM;
-
-        *l = nl;
-
-        for (i = k; i < k + n; i++) {
-                nl[i] = strdup(value);
-                if (!nl[i])
-                        goto rollback;
-        }
-
-        nl[i] = NULL;
-        return 0;
-
-rollback:
-        for (j = k; j < i; j++)
-                free(nl[j]);
-
-        nl[k] = NULL;
-        return -ENOMEM;
-}
-
-int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
-        bool b = false;
-        char **s;
-        int r;
-
-        /* Like fputs(), but for strv, and with a less stupid argument order */
-
-        if (!space)
-                space = &b;
-
-        STRV_FOREACH(s, l) {
-                r = fputs_with_space(f, *s, separator, space);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
-}
diff --git a/src/systemd/src/basic/strv.h b/src/systemd/src/basic/strv.h
deleted file mode 100644
index 51d03db9..00000000
--- a/src/systemd/src/basic/strv.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <fnmatch.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#include "alloc-util.h"
-#include "extract-word.h"
-#include "macro.h"
-#include "util.h"
-
-char *strv_find(char **l, const char *name) _pure_;
-char *strv_find_prefix(char **l, const char *name) _pure_;
-char *strv_find_startswith(char **l, const char *name) _pure_;
-
-char **strv_free(char **l);
-DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
-#define _cleanup_strv_free_ _cleanup_(strv_freep)
-
-char **strv_free_erase(char **l);
-DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
-#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
-
-void strv_clear(char **l);
-
-char **strv_copy(char * const *l);
-size_t strv_length(char * const *l) _pure_;
-
-int strv_extend_strv(char ***a, char **b, bool filter_duplicates);
-int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
-int strv_extend(char ***l, const char *value);
-int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
-int strv_extend_front(char ***l, const char *value);
-int strv_push(char ***l, char *value);
-int strv_push_pair(char ***l, char *a, char *b);
-int strv_insert(char ***l, size_t position, char *value);
-
-static inline int strv_push_prepend(char ***l, char *value) {
-        return strv_insert(l, 0, value);
-}
-
-int strv_consume(char ***l, char *value);
-int strv_consume_pair(char ***l, char *a, char *b);
-int strv_consume_prepend(char ***l, char *value);
-
-char **strv_remove(char **l, const char *s);
-char **strv_uniq(char **l);
-bool strv_is_uniq(char **l);
-
-bool strv_equal(char **a, char **b);
-
-#define strv_contains(l, s) (!!strv_find((l), (s)))
-
-char **strv_new(const char *x, ...) _sentinel_;
-char **strv_new_ap(const char *x, va_list ap);
-
-#define STRV_IGNORE ((const char *) -1)
-
-static inline const char* STRV_IFNOTNULL(const char *x) {
-        return x ? x : STRV_IGNORE;
-}
-
-static inline bool strv_isempty(char * const *l) {
-        return !l || !*l;
-}
-
-char **strv_split(const char *s, const char *separator);
-char **strv_split_newlines(const char *s);
-
-int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags);
-
-char *strv_join(char **l, const char *separator);
-
-char **strv_parse_nulstr(const char *s, size_t l);
-char **strv_split_nulstr(const char *s);
-int strv_make_nulstr(char **l, char **p, size_t *n);
-
-bool strv_overlap(char **a, char **b) _pure_;
-
-#define STRV_FOREACH(s, l)                      \
-        for ((s) = (l); (s) && *(s); (s)++)
-
-#define STRV_FOREACH_BACKWARDS(s, l)                                \
-        for (s = ({                                                 \
-                        char **_l = l;                              \
-                        _l ? _l + strv_length(_l) - 1U : NULL;      \
-                        });                                         \
-             (l) && ((s) >= (l));                                   \
-             (s)--)
-
-#define STRV_FOREACH_PAIR(x, y, l)               \
-        for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1))
-
-char **strv_sort(char **l);
-void strv_print(char **l);
-
-#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
-
-#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
-
-#define strv_from_stdarg_alloca(first)                          \
-        ({                                                      \
-                char **_l;                                      \
-                                                                \
-                if (!first)                                     \
-                        _l = (char**) &first;                   \
-                else {                                          \
-                        size_t _n;                              \
-                        va_list _ap;                            \
-                                                                \
-                        _n = 1;                                 \
-                        va_start(_ap, first);                   \
-                        while (va_arg(_ap, char*))              \
-                                _n++;                           \
-                        va_end(_ap);                            \
-                                                                \
-                        _l = newa(char*, _n+1);                 \
-                        _l[_n = 0] = (char*) first;             \
-                        va_start(_ap, first);                   \
-                        for (;;) {                              \
-                                _l[++_n] = va_arg(_ap, char*);  \
-                                if (!_l[_n])                    \
-                                        break;                  \
-                        }                                       \
-                        va_end(_ap);                            \
-                }                                               \
-                _l;                                             \
-        })
-
-#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
-#define STRPTR_IN_SET(x, ...)                                    \
-        ({                                                       \
-                const char* _x = (x);                            \
-                _x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \
-        })
-
-#define FOREACH_STRING(x, ...)                               \
-        for (char **_l = ({                                  \
-                char **_ll = STRV_MAKE(__VA_ARGS__);         \
-                x = _ll ? _ll[0] : NULL;                     \
-                _ll;                                         \
-        });                                                  \
-        _l && *_l;                                           \
-        x = ({                                               \
-                _l ++;                                       \
-                _l[0];                                       \
-        }))
-
-char **strv_reverse(char **l);
-char **strv_shell_escape(char **l, const char *bad);
-
-bool strv_fnmatch(char* const* patterns, const char *s, int flags);
-
-static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) {
-        assert(s);
-        return strv_isempty(patterns) ||
-               strv_fnmatch(patterns, s, flags);
-}
-
-char ***strv_free_free(char ***l);
-DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free);
-
-char **strv_skip(char **l, size_t n);
-
-int strv_extend_n(char ***l, const char *value, size_t n);
-
-int fputstrv(FILE *f, char **l, const char *separator, bool *space);
-
-#define strv_free_and_replace(a, b)             \
-        ({                                      \
-                strv_free(a);                   \
-                (a) = (b);                      \
-                (b) = NULL;                     \
-                0;                              \
-        })
diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c
deleted file mode 100644
index c0f53a47..00000000
--- a/src/systemd/src/basic/time-util.c
+++ /dev/null
@@ -1,1503 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/timerfd.h>
-#include <sys/timex.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "io-util.h"
-#include "log.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "stat-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-
-static clockid_t map_clock_id(clockid_t c) {
-
-        /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will
-         * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is
-         * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on
-         * those archs. */
-
-        switch (c) {
-
-        case CLOCK_BOOTTIME_ALARM:
-                return CLOCK_BOOTTIME;
-
-        case CLOCK_REALTIME_ALARM:
-                return CLOCK_REALTIME;
-
-        default:
-                return c;
-        }
-}
-
-usec_t now(clockid_t clock_id) {
-        struct timespec ts;
-
-        assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0);
-
-        return timespec_load(&ts);
-}
-
-nsec_t now_nsec(clockid_t clock_id) {
-        struct timespec ts;
-
-        assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0);
-
-        return timespec_load_nsec(&ts);
-}
-
-dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
-        assert(ts);
-
-        ts->realtime = now(CLOCK_REALTIME);
-        ts->monotonic = now(CLOCK_MONOTONIC);
-
-        return ts;
-}
-
-triple_timestamp* triple_timestamp_get(triple_timestamp *ts) {
-        assert(ts);
-
-        ts->realtime = now(CLOCK_REALTIME);
-        ts->monotonic = now(CLOCK_MONOTONIC);
-        ts->boottime = clock_boottime_supported() ? now(CLOCK_BOOTTIME) : USEC_INFINITY;
-
-        return ts;
-}
-
-dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
-        int64_t delta;
-        assert(ts);
-
-        if (u == USEC_INFINITY || u <= 0) {
-                ts->realtime = ts->monotonic = u;
-                return ts;
-        }
-
-        ts->realtime = u;
-
-        delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
-        ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
-
-        return ts;
-}
-
-triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) {
-        int64_t delta;
-
-        assert(ts);
-
-        if (u == USEC_INFINITY || u <= 0) {
-                ts->realtime = ts->monotonic = ts->boottime = u;
-                return ts;
-        }
-
-        ts->realtime = u;
-        delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
-        ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
-        ts->boottime = clock_boottime_supported() ? usec_sub_signed(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
-
-        return ts;
-}
-
-dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
-        int64_t delta;
-        assert(ts);
-
-        if (u == USEC_INFINITY) {
-                ts->realtime = ts->monotonic = USEC_INFINITY;
-                return ts;
-        }
-
-        ts->monotonic = u;
-        delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
-        ts->realtime = usec_sub_signed(now(CLOCK_REALTIME), delta);
-
-        return ts;
-}
-
-dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u) {
-        int64_t delta;
-
-        if (u == USEC_INFINITY) {
-                ts->realtime = ts->monotonic = USEC_INFINITY;
-                return ts;
-        }
-
-        dual_timestamp_get(ts);
-        delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
-        ts->realtime = usec_sub_signed(ts->realtime, delta);
-        ts->monotonic = usec_sub_signed(ts->monotonic, delta);
-
-        return ts;
-}
-
-usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) {
-
-        switch (clock) {
-
-        case CLOCK_REALTIME:
-        case CLOCK_REALTIME_ALARM:
-                return ts->realtime;
-
-        case CLOCK_MONOTONIC:
-                return ts->monotonic;
-
-        case CLOCK_BOOTTIME:
-        case CLOCK_BOOTTIME_ALARM:
-                return ts->boottime;
-
-        default:
-                return USEC_INFINITY;
-        }
-}
-
-usec_t timespec_load(const struct timespec *ts) {
-        assert(ts);
-
-        if (ts->tv_sec < 0 || ts->tv_nsec < 0)
-                return USEC_INFINITY;
-
-        if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
-                return USEC_INFINITY;
-
-        return
-                (usec_t) ts->tv_sec * USEC_PER_SEC +
-                (usec_t) ts->tv_nsec / NSEC_PER_USEC;
-}
-
-nsec_t timespec_load_nsec(const struct timespec *ts) {
-        assert(ts);
-
-        if (ts->tv_sec < 0 || ts->tv_nsec < 0)
-                return NSEC_INFINITY;
-
-        if ((nsec_t) ts->tv_sec >= (UINT64_MAX - ts->tv_nsec) / NSEC_PER_SEC)
-                return NSEC_INFINITY;
-
-        return (nsec_t) ts->tv_sec * NSEC_PER_SEC + (nsec_t) ts->tv_nsec;
-}
-
-struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
-        assert(ts);
-
-        if (u == USEC_INFINITY ||
-            u / USEC_PER_SEC >= TIME_T_MAX) {
-                ts->tv_sec = (time_t) -1;
-                ts->tv_nsec = (long) -1;
-                return ts;
-        }
-
-        ts->tv_sec = (time_t) (u / USEC_PER_SEC);
-        ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
-
-        return ts;
-}
-
-#if 0 /* NM_IGNORED */
-usec_t timeval_load(const struct timeval *tv) {
-        assert(tv);
-
-        if (tv->tv_sec < 0 || tv->tv_usec < 0)
-                return USEC_INFINITY;
-
-        if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC)
-                return USEC_INFINITY;
-
-        return
-                (usec_t) tv->tv_sec * USEC_PER_SEC +
-                (usec_t) tv->tv_usec;
-}
-
-struct timeval *timeval_store(struct timeval *tv, usec_t u) {
-        assert(tv);
-
-        if (u == USEC_INFINITY ||
-            u / USEC_PER_SEC > TIME_T_MAX) {
-                tv->tv_sec = (time_t) -1;
-                tv->tv_usec = (suseconds_t) -1;
-        } else {
-                tv->tv_sec = (time_t) (u / USEC_PER_SEC);
-                tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
-        }
-
-        return tv;
-}
-
-static char *format_timestamp_internal(
-                char *buf,
-                size_t l,
-                usec_t t,
-                bool utc,
-                bool us) {
-
-        /* The weekdays in non-localized (English) form. We use this instead of the localized form, so that our
-         * generated timestamps may be parsed with parse_timestamp(), and always read the same. */
-        static const char * const weekdays[] = {
-                [0] = "Sun",
-                [1] = "Mon",
-                [2] = "Tue",
-                [3] = "Wed",
-                [4] = "Thu",
-                [5] = "Fri",
-                [6] = "Sat",
-        };
-
-        struct tm tm;
-        time_t sec;
-        size_t n;
-
-        assert(buf);
-
-        if (l <
-            3 +                  /* week day */
-            1 + 10 +             /* space and date */
-            1 + 8 +              /* space and time */
-            (us ? 1 + 6 : 0) +   /* "." and microsecond part */
-            1 + 1 +              /* space and shortest possible zone */
-            1)
-                return NULL; /* Not enough space even for the shortest form. */
-        if (t <= 0 || t == USEC_INFINITY)
-                return NULL; /* Timestamp is unset */
-
-        /* Let's not format times with years > 9999 */
-        if (t > USEC_TIMESTAMP_FORMATTABLE_MAX) {
-                assert(l >= strlen("--- XXXX-XX-XX XX:XX:XX") + 1);
-                strcpy(buf, "--- XXXX-XX-XX XX:XX:XX");
-                return buf;
-        }
-
-        sec = (time_t) (t / USEC_PER_SEC); /* Round down */
-
-        if (!localtime_or_gmtime_r(&sec, &tm, utc))
-                return NULL;
-
-        /* Start with the week day */
-        assert((size_t) tm.tm_wday < ELEMENTSOF(weekdays));
-        memcpy(buf, weekdays[tm.tm_wday], 4);
-
-        /* Add the main components */
-        if (strftime(buf + 3, l - 3, " %Y-%m-%d %H:%M:%S", &tm) <= 0)
-                return NULL; /* Doesn't fit */
-
-        /* Append the microseconds part, if that's requested */
-        if (us) {
-                n = strlen(buf);
-                if (n + 8 > l)
-                        return NULL; /* Microseconds part doesn't fit. */
-
-                sprintf(buf + n, ".%06"PRI_USEC, t % USEC_PER_SEC);
-        }
-
-        /* Append the timezone */
-        n = strlen(buf);
-        if (utc) {
-                /* If this is UTC then let's explicitly use the "UTC" string here, because gmtime_r() normally uses the
-                 * obsolete "GMT" instead. */
-                if (n + 5 > l)
-                        return NULL; /* "UTC" doesn't fit. */
-
-                strcpy(buf + n, " UTC");
-
-        } else if (!isempty(tm.tm_zone)) {
-                size_t tn;
-
-                /* An explicit timezone is specified, let's use it, if it fits */
-                tn = strlen(tm.tm_zone);
-                if (n + 1 + tn + 1 > l) {
-                        /* The full time zone does not fit in. Yuck. */
-
-                        if (n + 1 + _POSIX_TZNAME_MAX + 1 > l)
-                                return NULL; /* Not even enough space for the POSIX minimum (of 6)? In that case, complain that it doesn't fit */
-
-                        /* So the time zone doesn't fit in fully, but the caller passed enough space for the POSIX
-                         * minimum time zone length. In this case suppress the timezone entirely, in order not to dump
-                         * an overly long, hard to read string on the user. This should be safe, because the user will
-                         * assume the local timezone anyway if none is shown. And so does parse_timestamp(). */
-                } else {
-                        buf[n++] = ' ';
-                        strcpy(buf + n, tm.tm_zone);
-                }
-        }
-
-        return buf;
-}
-
-char *format_timestamp(char *buf, size_t l, usec_t t) {
-        return format_timestamp_internal(buf, l, t, false, false);
-}
-
-char *format_timestamp_utc(char *buf, size_t l, usec_t t) {
-        return format_timestamp_internal(buf, l, t, true, false);
-}
-
-char *format_timestamp_us(char *buf, size_t l, usec_t t) {
-        return format_timestamp_internal(buf, l, t, false, true);
-}
-
-char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) {
-        return format_timestamp_internal(buf, l, t, true, true);
-}
-
-char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
-        const char *s;
-        usec_t n, d;
-
-        if (t <= 0 || t == USEC_INFINITY)
-                return NULL;
-
-        n = now(CLOCK_REALTIME);
-        if (n > t) {
-                d = n - t;
-                s = "ago";
-        } else {
-                d = t - n;
-                s = "left";
-        }
-
-        if (d >= USEC_PER_YEAR)
-                snprintf(buf, l, USEC_FMT " years " USEC_FMT " months %s",
-                         d / USEC_PER_YEAR,
-                         (d % USEC_PER_YEAR) / USEC_PER_MONTH, s);
-        else if (d >= USEC_PER_MONTH)
-                snprintf(buf, l, USEC_FMT " months " USEC_FMT " days %s",
-                         d / USEC_PER_MONTH,
-                         (d % USEC_PER_MONTH) / USEC_PER_DAY, s);
-        else if (d >= USEC_PER_WEEK)
-                snprintf(buf, l, USEC_FMT " weeks " USEC_FMT " days %s",
-                         d / USEC_PER_WEEK,
-                         (d % USEC_PER_WEEK) / USEC_PER_DAY, s);
-        else if (d >= 2*USEC_PER_DAY)
-                snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s);
-        else if (d >= 25*USEC_PER_HOUR)
-                snprintf(buf, l, "1 day " USEC_FMT "h %s",
-                         (d - USEC_PER_DAY) / USEC_PER_HOUR, s);
-        else if (d >= 6*USEC_PER_HOUR)
-                snprintf(buf, l, USEC_FMT "h %s",
-                         d / USEC_PER_HOUR, s);
-        else if (d >= USEC_PER_HOUR)
-                snprintf(buf, l, USEC_FMT "h " USEC_FMT "min %s",
-                         d / USEC_PER_HOUR,
-                         (d % USEC_PER_HOUR) / USEC_PER_MINUTE, s);
-        else if (d >= 5*USEC_PER_MINUTE)
-                snprintf(buf, l, USEC_FMT "min %s",
-                         d / USEC_PER_MINUTE, s);
-        else if (d >= USEC_PER_MINUTE)
-                snprintf(buf, l, USEC_FMT "min " USEC_FMT "s %s",
-                         d / USEC_PER_MINUTE,
-                         (d % USEC_PER_MINUTE) / USEC_PER_SEC, s);
-        else if (d >= USEC_PER_SEC)
-                snprintf(buf, l, USEC_FMT "s %s",
-                         d / USEC_PER_SEC, s);
-        else if (d >= USEC_PER_MSEC)
-                snprintf(buf, l, USEC_FMT "ms %s",
-                         d / USEC_PER_MSEC, s);
-        else if (d > 0)
-                snprintf(buf, l, USEC_FMT"us %s",
-                         d, s);
-        else
-                snprintf(buf, l, "now");
-
-        buf[l-1] = 0;
-        return buf;
-}
-#endif /* NM_IGNORED */
-
-char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
-        static const struct {
-                const char *suffix;
-                usec_t usec;
-        } table[] = {
-                { "y",     USEC_PER_YEAR   },
-                { "month", USEC_PER_MONTH  },
-                { "w",     USEC_PER_WEEK   },
-                { "d",     USEC_PER_DAY    },
-                { "h",     USEC_PER_HOUR   },
-                { "min",   USEC_PER_MINUTE },
-                { "s",     USEC_PER_SEC    },
-                { "ms",    USEC_PER_MSEC   },
-                { "us",    1               },
-        };
-
-        size_t i;
-        char *p = buf;
-        bool something = false;
-
-        assert(buf);
-        assert(l > 0);
-
-        if (t == USEC_INFINITY) {
-                strncpy(p, "infinity", l-1);
-                p[l-1] = 0;
-                return p;
-        }
-
-        if (t <= 0) {
-                strncpy(p, "0", l-1);
-                p[l-1] = 0;
-                return p;
-        }
-
-        /* The result of this function can be parsed with parse_sec */
-
-        for (i = 0; i < ELEMENTSOF(table); i++) {
-                int k = 0;
-                size_t n;
-                bool done = false;
-                usec_t a, b;
-
-                if (t <= 0)
-                        break;
-
-                if (t < accuracy && something)
-                        break;
-
-                if (t < table[i].usec)
-                        continue;
-
-                if (l <= 1)
-                        break;
-
-                a = t / table[i].usec;
-                b = t % table[i].usec;
-
-                /* Let's see if we should shows this in dot notation */
-                if (t < USEC_PER_MINUTE && b > 0) {
-                        usec_t cc;
-                        signed char j;
-
-                        j = 0;
-                        for (cc = table[i].usec; cc > 1; cc /= 10)
-                                j++;
-
-                        for (cc = accuracy; cc > 1; cc /= 10) {
-                                b /= 10;
-                                j--;
-                        }
-
-                        if (j > 0) {
-                                k = snprintf(p, l,
-                                             "%s"USEC_FMT".%0*"PRI_USEC"%s",
-                                             p > buf ? " " : "",
-                                             a,
-                                             j,
-                                             b,
-                                             table[i].suffix);
-
-                                t = 0;
-                                done = true;
-                        }
-                }
-
-                /* No? Then let's show it normally */
-                if (!done) {
-                        k = snprintf(p, l,
-                                     "%s"USEC_FMT"%s",
-                                     p > buf ? " " : "",
-                                     a,
-                                     table[i].suffix);
-
-                        t = b;
-                }
-
-                n = MIN((size_t) k, l);
-
-                l -= n;
-                p += n;
-
-                something = true;
-        }
-
-        *p = 0;
-
-        return buf;
-}
-
-#if 0 /* NM_IGNORED */
-void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
-
-        assert(f);
-        assert(name);
-        assert(t);
-
-        if (!dual_timestamp_is_set(t))
-                return;
-
-        fprintf(f, "%s="USEC_FMT" "USEC_FMT"\n",
-                name,
-                t->realtime,
-                t->monotonic);
-}
-
-int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
-        uint64_t a, b;
-        int r, pos;
-
-        assert(value);
-        assert(t);
-
-        pos = strspn(value, WHITESPACE);
-        if (value[pos] == '-')
-                return -EINVAL;
-        pos += strspn(value + pos, DIGITS);
-        pos += strspn(value + pos, WHITESPACE);
-        if (value[pos] == '-')
-                return -EINVAL;
-
-        r = sscanf(value, "%" PRIu64 "%" PRIu64 "%n", &a, &b, &pos);
-        if (r != 2) {
-                log_debug("Failed to parse dual timestamp value \"%s\".", value);
-                return -EINVAL;
-        }
-
-        if (value[pos] != '\0')
-                /* trailing garbage */
-                return -EINVAL;
-
-        t->realtime = a;
-        t->monotonic = b;
-
-        return 0;
-}
-
-int timestamp_deserialize(const char *value, usec_t *timestamp) {
-        int r;
-
-        assert(value);
-
-        r = safe_atou64(value, timestamp);
-        if (r < 0)
-                return log_debug_errno(r, "Failed to parse timestamp value \"%s\": %m", value);
-
-        return r;
-}
-
-static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
-        static const struct {
-                const char *name;
-                const int nr;
-        } day_nr[] = {
-                { "Sunday",    0 },
-                { "Sun",       0 },
-                { "Monday",    1 },
-                { "Mon",       1 },
-                { "Tuesday",   2 },
-                { "Tue",       2 },
-                { "Wednesday", 3 },
-                { "Wed",       3 },
-                { "Thursday",  4 },
-                { "Thu",       4 },
-                { "Friday",    5 },
-                { "Fri",       5 },
-                { "Saturday",  6 },
-                { "Sat",       6 },
-        };
-
-        const char *k, *utc = NULL, *tzn = NULL;
-        struct tm tm, copy;
-        time_t x;
-        usec_t x_usec, plus = 0, minus = 0, ret;
-        int r, weekday = -1, dst = -1;
-        size_t i;
-
-        /* Allowed syntaxes:
-         *
-         *   2012-09-22 16:34:22
-         *   2012-09-22 16:34     (seconds will be set to 0)
-         *   2012-09-22           (time will be set to 00:00:00)
-         *   16:34:22             (date will be set to today)
-         *   16:34                (date will be set to today, seconds to 0)
-         *   now
-         *   yesterday            (time is set to 00:00:00)
-         *   today                (time is set to 00:00:00)
-         *   tomorrow             (time is set to 00:00:00)
-         *   +5min
-         *   -5days
-         *   @2147483647          (seconds since epoch)
-         */
-
-        assert(t);
-        assert(usec);
-
-        if (t[0] == '@' && !with_tz)
-                return parse_sec(t + 1, usec);
-
-        ret = now(CLOCK_REALTIME);
-
-        if (!with_tz) {
-                if (streq(t, "now"))
-                        goto finish;
-
-                else if (t[0] == '+') {
-                        r = parse_sec(t+1, &plus);
-                        if (r < 0)
-                                return r;
-
-                        goto finish;
-
-                } else if (t[0] == '-') {
-                        r = parse_sec(t+1, &minus);
-                        if (r < 0)
-                                return r;
-
-                        goto finish;
-
-                } else if ((k = endswith(t, " ago"))) {
-                        t = strndupa(t, k - t);
-
-                        r = parse_sec(t, &minus);
-                        if (r < 0)
-                                return r;
-
-                        goto finish;
-
-                } else if ((k = endswith(t, " left"))) {
-                        t = strndupa(t, k - t);
-
-                        r = parse_sec(t, &plus);
-                        if (r < 0)
-                                return r;
-
-                        goto finish;
-                }
-
-                /* See if the timestamp is suffixed with UTC */
-                utc = endswith_no_case(t, " UTC");
-                if (utc)
-                        t = strndupa(t, utc - t);
-                else {
-                        const char *e = NULL;
-                        int j;
-
-                        tzset();
-
-                        /* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only
-                         * support the local timezones here, nothing else. Not because we wouldn't want to, but simply because
-                         * there are no nice APIs available to cover this. By accepting the local time zone strings, we make
-                         * sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't
-                         * support arbitrary timezone specifications. */
-
-                        for (j = 0; j <= 1; j++) {
-
-                                if (isempty(tzname[j]))
-                                        continue;
-
-                                e = endswith_no_case(t, tzname[j]);
-                                if (!e)
-                                        continue;
-                                if (e == t)
-                                        continue;
-                                if (e[-1] != ' ')
-                                        continue;
-
-                                break;
-                        }
-
-                        if (IN_SET(j, 0, 1)) {
-                                /* Found one of the two timezones specified. */
-                                t = strndupa(t, e - t - 1);
-                                dst = j;
-                                tzn = tzname[j];
-                        }
-                }
-        }
-
-        x = (time_t) (ret / USEC_PER_SEC);
-        x_usec = 0;
-
-        if (!localtime_or_gmtime_r(&x, &tm, utc))
-                return -EINVAL;
-
-        tm.tm_isdst = dst;
-        if (!with_tz && tzn)
-                tm.tm_zone = tzn;
-
-        if (streq(t, "today")) {
-                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-                goto from_tm;
-
-        } else if (streq(t, "yesterday")) {
-                tm.tm_mday--;
-                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-                goto from_tm;
-
-        } else if (streq(t, "tomorrow")) {
-                tm.tm_mday++;
-                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-                goto from_tm;
-        }
-
-        for (i = 0; i < ELEMENTSOF(day_nr); i++) {
-                size_t skip;
-
-                if (!startswith_no_case(t, day_nr[i].name))
-                        continue;
-
-                skip = strlen(day_nr[i].name);
-                if (t[skip] != ' ')
-                        continue;
-
-                weekday = day_nr[i].nr;
-                t += skip + 1;
-                break;
-        }
-
-        copy = tm;
-        k = strptime(t, "%y-%m-%d %H:%M:%S", &tm);
-        if (k) {
-                if (*k == '.')
-                        goto parse_usec;
-                else if (*k == 0)
-                        goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm);
-        if (k) {
-                if (*k == '.')
-                        goto parse_usec;
-                else if (*k == 0)
-                        goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%y-%m-%d %H:%M", &tm);
-        if (k && *k == 0) {
-                tm.tm_sec = 0;
-                goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%Y-%m-%d %H:%M", &tm);
-        if (k && *k == 0) {
-                tm.tm_sec = 0;
-                goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%y-%m-%d", &tm);
-        if (k && *k == 0) {
-                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-                goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%Y-%m-%d", &tm);
-        if (k && *k == 0) {
-                tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-                goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%H:%M:%S", &tm);
-        if (k) {
-                if (*k == '.')
-                        goto parse_usec;
-                else if (*k == 0)
-                        goto from_tm;
-        }
-
-        tm = copy;
-        k = strptime(t, "%H:%M", &tm);
-        if (k && *k == 0) {
-                tm.tm_sec = 0;
-                goto from_tm;
-        }
-
-        return -EINVAL;
-
-parse_usec:
-        {
-                unsigned add;
-
-                k++;
-                r = parse_fractional_part_u(&k, 6, &add);
-                if (r < 0)
-                        return -EINVAL;
-
-                if (*k)
-                        return -EINVAL;
-
-                x_usec = add;
-        }
-
-from_tm:
-        if (weekday >= 0 && tm.tm_wday != weekday)
-                return -EINVAL;
-
-        x = mktime_or_timegm(&tm, utc);
-        if (x < 0)
-                return -EINVAL;
-
-        ret = (usec_t) x * USEC_PER_SEC + x_usec;
-        if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
-                return -EINVAL;
-
-finish:
-        if (ret + plus < ret) /* overflow? */
-                return -EINVAL;
-        ret += plus;
-        if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
-                return -EINVAL;
-
-        if (ret >= minus)
-                ret -= minus;
-        else
-                return -EINVAL;
-
-        *usec = ret;
-
-        return 0;
-}
-
-typedef struct ParseTimestampResult {
-        usec_t usec;
-        int return_value;
-} ParseTimestampResult;
-
-int parse_timestamp(const char *t, usec_t *usec) {
-        char *last_space, *tz = NULL;
-        ParseTimestampResult *shared, tmp;
-        int r;
-
-        last_space = strrchr(t, ' ');
-        if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG))
-                tz = last_space + 1;
-
-        if (!tz || endswith_no_case(t, " UTC"))
-                return parse_timestamp_impl(t, usec, false);
-
-        shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
-        if (shared == MAP_FAILED)
-                return negative_errno();
-
-        r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL);
-        if (r < 0) {
-                (void) munmap(shared, sizeof *shared);
-                return r;
-        }
-        if (r == 0) {
-                bool with_tz = true;
-
-                if (setenv("TZ", tz, 1) != 0) {
-                        shared->return_value = negative_errno();
-                        _exit(EXIT_FAILURE);
-                }
-
-                tzset();
-
-                /* If there is a timezone that matches the tzname fields, leave the parsing to the implementation.
-                 * Otherwise just cut it off. */
-                with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]);
-
-                /* Cut off the timezone if we dont need it. */
-                if (with_tz)
-                        t = strndupa(t, last_space - t);
-
-                shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz);
-
-                _exit(EXIT_SUCCESS);
-        }
-
-        tmp = *shared;
-        if (munmap(shared, sizeof *shared) != 0)
-                return negative_errno();
-
-        if (tmp.return_value == 0)
-                *usec = tmp.usec;
-
-        return tmp.return_value;
-}
-
-static char* extract_multiplier(char *p, usec_t *multiplier) {
-        static const struct {
-                const char *suffix;
-                usec_t usec;
-        } table[] = {
-                { "seconds", USEC_PER_SEC    },
-                { "second",  USEC_PER_SEC    },
-                { "sec",     USEC_PER_SEC    },
-                { "s",       USEC_PER_SEC    },
-                { "minutes", USEC_PER_MINUTE },
-                { "minute",  USEC_PER_MINUTE },
-                { "min",     USEC_PER_MINUTE },
-                { "months",  USEC_PER_MONTH  },
-                { "month",   USEC_PER_MONTH  },
-                { "M",       USEC_PER_MONTH  },
-                { "msec",    USEC_PER_MSEC   },
-                { "ms",      USEC_PER_MSEC   },
-                { "m",       USEC_PER_MINUTE },
-                { "hours",   USEC_PER_HOUR   },
-                { "hour",    USEC_PER_HOUR   },
-                { "hr",      USEC_PER_HOUR   },
-                { "h",       USEC_PER_HOUR   },
-                { "days",    USEC_PER_DAY    },
-                { "day",     USEC_PER_DAY    },
-                { "d",       USEC_PER_DAY    },
-                { "weeks",   USEC_PER_WEEK   },
-                { "week",    USEC_PER_WEEK   },
-                { "w",       USEC_PER_WEEK   },
-                { "years",   USEC_PER_YEAR   },
-                { "year",    USEC_PER_YEAR   },
-                { "y",       USEC_PER_YEAR   },
-                { "usec",    1ULL            },
-                { "us",      1ULL            },
-                { "µs",      1ULL            },
-        };
-        size_t i;
-
-        for (i = 0; i < ELEMENTSOF(table); i++) {
-                char *e;
-
-                e = startswith(p, table[i].suffix);
-                if (e) {
-                        *multiplier = table[i].usec;
-                        return e;
-                }
-        }
-
-        return p;
-}
-
-int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
-        const char *p, *s;
-        usec_t r = 0;
-        bool something = false;
-
-        assert(t);
-        assert(usec);
-        assert(default_unit > 0);
-
-        p = t;
-
-        p += strspn(p, WHITESPACE);
-        s = startswith(p, "infinity");
-        if (s) {
-                s += strspn(s, WHITESPACE);
-                if (*s != 0)
-                        return -EINVAL;
-
-                *usec = USEC_INFINITY;
-                return 0;
-        }
-
-        for (;;) {
-                usec_t multiplier = default_unit, k;
-                long long l, z = 0;
-                unsigned n = 0;
-                char *e;
-
-                p += strspn(p, WHITESPACE);
-
-                if (*p == 0) {
-                        if (!something)
-                                return -EINVAL;
-
-                        break;
-                }
-
-                if (*p == '-') /* Don't allow "-0" */
-                        return -ERANGE;
-
-                errno = 0;
-                l = strtoll(p, &e, 10);
-                if (errno > 0)
-                        return -errno;
-                if (l < 0)
-                        return -ERANGE;
-
-                if (*e == '.') {
-                        char *b = e + 1;
-
-                        /* Don't allow "0.-0", "3.+1" or "3. 1" */
-                        if (*b == '-' || *b == '+' || isspace(*b))
-                                return -EINVAL;
-
-                        errno = 0;
-                        z = strtoll(b, &e, 10);
-                        if (errno > 0)
-                                return -errno;
-                        if (z < 0)
-                                return -ERANGE;
-                        if (e == b)
-                                return -EINVAL;
-
-                        n = e - b;
-
-                } else if (e == p)
-                        return -EINVAL;
-
-                e += strspn(e, WHITESPACE);
-                p = extract_multiplier(e, &multiplier);
-
-                something = true;
-
-                k = (usec_t) z * multiplier;
-
-                for (; n > 0; n--)
-                        k /= 10;
-
-                r += (usec_t) l * multiplier + k;
-        }
-
-        *usec = r;
-
-        return 0;
-}
-
-int parse_sec(const char *t, usec_t *usec) {
-        return parse_time(t, usec, USEC_PER_SEC);
-}
-
-int parse_sec_fix_0(const char *t, usec_t *usec) {
-        assert(t);
-        assert(usec);
-
-        t += strspn(t, WHITESPACE);
-
-        if (streq(t, "0")) {
-                *usec = USEC_INFINITY;
-                return 0;
-        }
-
-        return parse_sec(t, usec);
-}
-
-int parse_nsec(const char *t, nsec_t *nsec) {
-        static const struct {
-                const char *suffix;
-                nsec_t nsec;
-        } table[] = {
-                { "seconds", NSEC_PER_SEC },
-                { "second", NSEC_PER_SEC },
-                { "sec", NSEC_PER_SEC },
-                { "s", NSEC_PER_SEC },
-                { "minutes", NSEC_PER_MINUTE },
-                { "minute", NSEC_PER_MINUTE },
-                { "min", NSEC_PER_MINUTE },
-                { "months", NSEC_PER_MONTH },
-                { "month", NSEC_PER_MONTH },
-                { "msec", NSEC_PER_MSEC },
-                { "ms", NSEC_PER_MSEC },
-                { "m", NSEC_PER_MINUTE },
-                { "hours", NSEC_PER_HOUR },
-                { "hour", NSEC_PER_HOUR },
-                { "hr", NSEC_PER_HOUR },
-                { "h", NSEC_PER_HOUR },
-                { "days", NSEC_PER_DAY },
-                { "day", NSEC_PER_DAY },
-                { "d", NSEC_PER_DAY },
-                { "weeks", NSEC_PER_WEEK },
-                { "week", NSEC_PER_WEEK },
-                { "w", NSEC_PER_WEEK },
-                { "years", NSEC_PER_YEAR },
-                { "year", NSEC_PER_YEAR },
-                { "y", NSEC_PER_YEAR },
-                { "usec", NSEC_PER_USEC },
-                { "us", NSEC_PER_USEC },
-                { "µs", NSEC_PER_USEC },
-                { "nsec", 1ULL },
-                { "ns", 1ULL },
-                { "", 1ULL }, /* default is nsec */
-        };
-
-        const char *p, *s;
-        nsec_t r = 0;
-        bool something = false;
-
-        assert(t);
-        assert(nsec);
-
-        p = t;
-
-        p += strspn(p, WHITESPACE);
-        s = startswith(p, "infinity");
-        if (s) {
-                s += strspn(s, WHITESPACE);
-                if (*s != 0)
-                        return -EINVAL;
-
-                *nsec = NSEC_INFINITY;
-                return 0;
-        }
-
-        for (;;) {
-                long long l, z = 0;
-                size_t n = 0, i;
-                char *e;
-
-                p += strspn(p, WHITESPACE);
-
-                if (*p == 0) {
-                        if (!something)
-                                return -EINVAL;
-
-                        break;
-                }
-
-                if (*p == '-')
-                        return -ERANGE;
-
-                errno = 0;
-                l = strtoll(p, &e, 10);
-                if (errno > 0)
-                        return -errno;
-                if (l < 0)
-                        return -ERANGE;
-
-                if (*e == '.') {
-                        char *b = e + 1;
-
-                        if (*b == '-' || *b == '+' || isspace(*b))
-                                return -EINVAL;
-
-                        errno = 0;
-                        z = strtoll(b, &e, 10);
-                        if (errno > 0)
-                                return -errno;
-                        if (z < 0)
-                                return -ERANGE;
-                        if (e == b)
-                                return -EINVAL;
-
-                        n = e - b;
-
-                } else if (e == p)
-                        return -EINVAL;
-
-                e += strspn(e, WHITESPACE);
-
-                for (i = 0; i < ELEMENTSOF(table); i++)
-                        if (startswith(e, table[i].suffix)) {
-                                nsec_t k = (nsec_t) z * table[i].nsec;
-
-                                for (; n > 0; n--)
-                                        k /= 10;
-
-                                r += (nsec_t) l * table[i].nsec + k;
-                                p = e + strlen(table[i].suffix);
-
-                                something = true;
-                                break;
-                        }
-
-                if (i >= ELEMENTSOF(table))
-                        return -EINVAL;
-
-        }
-
-        *nsec = r;
-
-        return 0;
-}
-
-bool ntp_synced(void) {
-        struct timex txc = {};
-
-        if (adjtimex(&txc) < 0)
-                return false;
-
-        if (txc.status & STA_UNSYNC)
-                return false;
-
-        return true;
-}
-
-int get_timezones(char ***ret) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_strv_free_ char **zones = NULL;
-        size_t n_zones = 0, n_allocated = 0;
-
-        assert(ret);
-
-        zones = strv_new("UTC", NULL);
-        if (!zones)
-                return -ENOMEM;
-
-        n_allocated = 2;
-        n_zones = 1;
-
-        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
-        if (f) {
-                char l[LINE_MAX];
-
-                FOREACH_LINE(l, f, return -errno) {
-                        char *p, *w;
-                        size_t k;
-
-                        p = strstrip(l);
-
-                        if (isempty(p) || *p == '#')
-                                continue;
-
-                        /* Skip over country code */
-                        p += strcspn(p, WHITESPACE);
-                        p += strspn(p, WHITESPACE);
-
-                        /* Skip over coordinates */
-                        p += strcspn(p, WHITESPACE);
-                        p += strspn(p, WHITESPACE);
-
-                        /* Found timezone name */
-                        k = strcspn(p, WHITESPACE);
-                        if (k <= 0)
-                                continue;
-
-                        w = strndup(p, k);
-                        if (!w)
-                                return -ENOMEM;
-
-                        if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2)) {
-                                free(w);
-                                return -ENOMEM;
-                        }
-
-                        zones[n_zones++] = w;
-                        zones[n_zones] = NULL;
-                }
-
-                strv_sort(zones);
-
-        } else if (errno != ENOENT)
-                return -errno;
-
-        *ret = TAKE_PTR(zones);
-
-        return 0;
-}
-#endif /* NM_IGNORED */
-
-bool timezone_is_valid(const char *name, int log_level) {
-        bool slash = false;
-        const char *p, *t;
-        _cleanup_close_ int fd = -1;
-        char buf[4];
-        int r;
-
-        if (isempty(name))
-                return false;
-
-        if (name[0] == '/')
-                return false;
-
-        for (p = name; *p; p++) {
-                if (!(*p >= '0' && *p <= '9') &&
-                    !(*p >= 'a' && *p <= 'z') &&
-                    !(*p >= 'A' && *p <= 'Z') &&
-                    !IN_SET(*p, '-', '_', '+', '/'))
-                        return false;
-
-                if (*p == '/') {
-
-                        if (slash)
-                                return false;
-
-                        slash = true;
-                } else
-                        slash = false;
-        }
-
-        if (slash)
-                return false;
-
-        if (p - name >= PATH_MAX)
-                return false;
-
-        t = strjoina("/usr/share/zoneinfo/", name);
-
-        fd = open(t, O_RDONLY|O_CLOEXEC);
-        if (fd < 0) {
-                log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
-                return false;
-        }
-
-        r = fd_verify_regular(fd);
-        if (r < 0) {
-                log_full_errno(log_level, r, "Timezone file '%s' is not  a regular file: %m", t);
-                return false;
-        }
-
-        r = loop_read_exact(fd, buf, 4, false);
-        if (r < 0) {
-                log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
-                return false;
-        }
-
-        /* Magic from tzfile(5) */
-        if (memcmp(buf, "TZif", 4) != 0) {
-                log_full(log_level, "Timezone file '%s' has wrong magic bytes", t);
-                return false;
-        }
-
-        return true;
-}
-
-bool clock_boottime_supported(void) {
-        static int supported = -1;
-
-        /* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */
-
-        if (supported < 0) {
-                int fd;
-
-                fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
-                if (fd < 0)
-                        supported = false;
-                else {
-                        safe_close(fd);
-                        supported = true;
-                }
-        }
-
-        return supported;
-}
-
-clockid_t clock_boottime_or_monotonic(void) {
-        if (clock_boottime_supported())
-                return CLOCK_BOOTTIME;
-        else
-                return CLOCK_MONOTONIC;
-}
-
-bool clock_supported(clockid_t clock) {
-        struct timespec ts;
-
-        switch (clock) {
-
-        case CLOCK_MONOTONIC:
-        case CLOCK_REALTIME:
-                return true;
-
-        case CLOCK_BOOTTIME:
-                return clock_boottime_supported();
-
-        case CLOCK_BOOTTIME_ALARM:
-                if (!clock_boottime_supported())
-                        return false;
-
-                _fallthrough_;
-        default:
-                /* For everything else, check properly */
-                return clock_gettime(clock, &ts) >= 0;
-        }
-}
-
-#if 0 /* NM_IGNORED */
-int get_timezone(char **tz) {
-        _cleanup_free_ char *t = NULL;
-        const char *e;
-        char *z;
-        int r;
-
-        r = readlink_malloc("/etc/localtime", &t);
-        if (r < 0)
-                return r; /* returns EINVAL if not a symlink */
-
-        e = path_startswith(t, "/usr/share/zoneinfo/");
-        if (!e)
-                e = path_startswith(t, "../usr/share/zoneinfo/");
-        if (!e)
-                return -EINVAL;
-
-        if (!timezone_is_valid(e, LOG_DEBUG))
-                return -EINVAL;
-
-        z = strdup(e);
-        if (!z)
-                return -ENOMEM;
-
-        *tz = z;
-        return 0;
-}
-
-time_t mktime_or_timegm(struct tm *tm, bool utc) {
-        return utc ? timegm(tm) : mktime(tm);
-}
-
-struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) {
-        return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
-}
-
-unsigned long usec_to_jiffies(usec_t u) {
-        static thread_local unsigned long hz = 0;
-        long r;
-
-        if (hz == 0) {
-                r = sysconf(_SC_CLK_TCK);
-
-                assert(r > 0);
-                hz = r;
-        }
-
-        return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
-}
-
-usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
-        usec_t a, b;
-
-        if (x == USEC_INFINITY)
-                return USEC_INFINITY;
-        if (map_clock_id(from) == map_clock_id(to))
-                return x;
-
-        a = now(from);
-        b = now(to);
-
-        if (x > a)
-                /* x lies in the future */
-                return usec_add(b, usec_sub_unsigned(x, a));
-        else
-                /* x lies in the past */
-                return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
-}
-
-bool in_utc_timezone(void) {
-        tzset();
-
-        return timezone == 0 && daylight == 0;
-}
-
-int time_change_fd(void) {
-
-        /* We only care for the cancellation event, hence we set the timeout to the latest possible value. */
-        static const struct itimerspec its = {
-                .it_value.tv_sec = TIME_T_MAX,
-        };
-
-        _cleanup_close_ int fd;
-
-        assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
-
-        /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever CLOCK_REALTIME makes a jump relative to
-         * CLOCK_MONOTONIC. */
-
-        fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
-        if (fd < 0)
-                return -errno;
-
-        if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
-                return -errno;
-
-        return TAKE_FD(fd);
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/time-util.h b/src/systemd/src/basic/time-util.h
deleted file mode 100644
index 344f2dc5..00000000
--- a/src/systemd/src/basic/time-util.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <inttypes.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
-
-typedef uint64_t usec_t;
-typedef uint64_t nsec_t;
-
-#define PRI_NSEC PRIu64
-#define PRI_USEC PRIu64
-#define NSEC_FMT "%" PRI_NSEC
-#define USEC_FMT "%" PRI_USEC
-
-#include "macro.h"
-
-typedef struct dual_timestamp {
-        usec_t realtime;
-        usec_t monotonic;
-} dual_timestamp;
-
-typedef struct triple_timestamp {
-        usec_t realtime;
-        usec_t monotonic;
-        usec_t boottime;
-} triple_timestamp;
-
-#define USEC_INFINITY ((usec_t) -1)
-#define NSEC_INFINITY ((nsec_t) -1)
-
-#define MSEC_PER_SEC  1000ULL
-#define USEC_PER_SEC  ((usec_t) 1000000ULL)
-#define USEC_PER_MSEC ((usec_t) 1000ULL)
-#define NSEC_PER_SEC  ((nsec_t) 1000000000ULL)
-#define NSEC_PER_MSEC ((nsec_t) 1000000ULL)
-#define NSEC_PER_USEC ((nsec_t) 1000ULL)
-
-#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC))
-#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC))
-#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE))
-#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE))
-#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR))
-#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR))
-#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY))
-#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY))
-#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC))
-#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC))
-#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
-#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC))
-
-/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this
- * to 6. Let's rely on that. */
-#define FORMAT_TIMESTAMP_MAX (3+1+10+1+8+1+6+1+6+1)
-#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */
-#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
-#define FORMAT_TIMESPAN_MAX 64
-
-#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1)
-
-#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) {})
-#define TRIPLE_TIMESTAMP_NULL ((struct triple_timestamp) {})
-
-usec_t now(clockid_t clock);
-nsec_t now_nsec(clockid_t clock);
-
-dual_timestamp* dual_timestamp_get(dual_timestamp *ts);
-dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u);
-dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u);
-dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u);
-
-triple_timestamp* triple_timestamp_get(triple_timestamp *ts);
-triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u);
-
-#define DUAL_TIMESTAMP_HAS_CLOCK(clock)                               \
-        IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC)
-
-#define TRIPLE_TIMESTAMP_HAS_CLOCK(clock)                               \
-        IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM)
-
-static inline bool dual_timestamp_is_set(const dual_timestamp *ts) {
-        return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) ||
-                (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY));
-}
-
-static inline bool triple_timestamp_is_set(const triple_timestamp *ts) {
-        return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) ||
-                (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY) ||
-                (ts->boottime > 0 && ts->boottime != USEC_INFINITY));
-}
-
-usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock);
-
-usec_t timespec_load(const struct timespec *ts) _pure_;
-nsec_t timespec_load_nsec(const struct timespec *ts) _pure_;
-struct timespec *timespec_store(struct timespec *ts, usec_t u);
-
-usec_t timeval_load(const struct timeval *tv) _pure_;
-struct timeval *timeval_store(struct timeval *tv, usec_t u);
-
-char *format_timestamp(char *buf, size_t l, usec_t t);
-char *format_timestamp_utc(char *buf, size_t l, usec_t t);
-char *format_timestamp_us(char *buf, size_t l, usec_t t);
-char *format_timestamp_us_utc(char *buf, size_t l, usec_t t);
-char *format_timestamp_relative(char *buf, size_t l, usec_t t);
-char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
-
-void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
-int dual_timestamp_deserialize(const char *value, dual_timestamp *t);
-int timestamp_deserialize(const char *value, usec_t *timestamp);
-
-int parse_timestamp(const char *t, usec_t *usec);
-
-int parse_sec(const char *t, usec_t *usec);
-int parse_sec_fix_0(const char *t, usec_t *usec);
-int parse_time(const char *t, usec_t *usec, usec_t default_unit);
-int parse_nsec(const char *t, nsec_t *nsec);
-
-bool ntp_synced(void);
-
-int get_timezones(char ***l);
-bool timezone_is_valid(const char *name, int log_level);
-
-bool clock_boottime_supported(void);
-bool clock_supported(clockid_t clock);
-clockid_t clock_boottime_or_monotonic(void);
-
-usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
-
-int get_timezone(char **timezone);
-
-time_t mktime_or_timegm(struct tm *tm, bool utc);
-struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
-
-unsigned long usec_to_jiffies(usec_t usec);
-
-bool in_utc_timezone(void);
-
-static inline usec_t usec_add(usec_t a, usec_t b) {
-        usec_t c;
-
-        /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't
-         * overflow. */
-
-        c = a + b;
-        if (c < a || c < b) /* overflow check */
-                return USEC_INFINITY;
-
-        return c;
-}
-
-static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) {
-
-        if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
-                return USEC_INFINITY;
-        if (timestamp < delta)
-                return 0;
-
-        return timestamp - delta;
-}
-
-static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
-        if (delta < 0)
-                return usec_add(timestamp, (usec_t) (-delta));
-        else
-                return usec_sub_unsigned(timestamp, (usec_t) delta);
-}
-
-#if SIZEOF_TIME_T == 8
-/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
- * territory. However, since we want to stay away from this in all timezones we take one day off. */
-#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000)
-#elif SIZEOF_TIME_T == 4
-/* With a 32bit time_t we can't go beyond 2038... */
-#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000)
-#else
-#error "Yuck, time_t is neither 4 nor 8 bytes wide?"
-#endif
-
-int time_change_fd(void);
diff --git a/src/systemd/src/basic/umask-util.h b/src/systemd/src/basic/umask-util.h
deleted file mode 100644
index e964292e..00000000
--- a/src/systemd/src/basic/umask-util.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "macro.h"
-
-static inline void umaskp(mode_t *u) {
-        umask(*u);
-}
-
-#define _cleanup_umask_ _cleanup_(umaskp)
-
-struct _umask_struct_ {
-        mode_t mask;
-        bool quit;
-};
-
-static inline void _reset_umask_(struct _umask_struct_ *s) {
-        umask(s->mask);
-};
-
-#define RUN_WITH_UMASK(mask)                                            \
-        for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \
-             !_saved_umask_.quit ;                                      \
-             _saved_umask_.quit = true)
diff --git a/src/systemd/src/basic/utf8.c b/src/systemd/src/basic/utf8.c
deleted file mode 100644
index 7238bca7..00000000
--- a/src/systemd/src/basic/utf8.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-/* Parts of this file are based on the GLIB utf8 validation functions. The
- * original license text follows. */
-
-/* gutf8.c - Operations on UTF-8 strings.
- *
- * Copyright (C) 1999 Tom Tromey
- * Copyright (C) 2000 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "nm-sd-adapt.h"
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "gunicode.h"
-#include "hexdecoct.h"
-#include "macro.h"
-#include "utf8.h"
-
-bool unichar_is_valid(char32_t ch) {
-
-        if (ch >= 0x110000) /* End of unicode space */
-                return false;
-        if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */
-                return false;
-        if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */
-                return false;
-        if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */
-                return false;
-
-        return true;
-}
-
-static bool unichar_is_control(char32_t ch) {
-
-        /*
-          0 to ' '-1 is the C0 range.
-          DEL=0x7F, and DEL+1 to 0x9F is C1 range.
-          '\t' is in C0 range, but more or less harmless and commonly used.
-        */
-
-        return (ch < ' ' && !IN_SET(ch, '\t', '\n')) ||
-                (0x7F <= ch && ch <= 0x9F);
-}
-
-/* count of characters used to encode one unicode char */
-static int utf8_encoded_expected_len(const char *str) {
-        unsigned char c;
-
-        assert(str);
-
-        c = (unsigned char) str[0];
-        if (c < 0x80)
-                return 1;
-        if ((c & 0xe0) == 0xc0)
-                return 2;
-        if ((c & 0xf0) == 0xe0)
-                return 3;
-        if ((c & 0xf8) == 0xf0)
-                return 4;
-        if ((c & 0xfc) == 0xf8)
-                return 5;
-        if ((c & 0xfe) == 0xfc)
-                return 6;
-
-        return 0;
-}
-
-/* decode one unicode char */
-int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
-        char32_t unichar;
-        int len, i;
-
-        assert(str);
-
-        len = utf8_encoded_expected_len(str);
-
-        switch (len) {
-        case 1:
-                *ret_unichar = (char32_t)str[0];
-                return 0;
-        case 2:
-                unichar = str[0] & 0x1f;
-                break;
-        case 3:
-                unichar = (char32_t)str[0] & 0x0f;
-                break;
-        case 4:
-                unichar = (char32_t)str[0] & 0x07;
-                break;
-        case 5:
-                unichar = (char32_t)str[0] & 0x03;
-                break;
-        case 6:
-                unichar = (char32_t)str[0] & 0x01;
-                break;
-        default:
-                return -EINVAL;
-        }
-
-        for (i = 1; i < len; i++) {
-                if (((char32_t)str[i] & 0xc0) != 0x80)
-                        return -EINVAL;
-                unichar <<= 6;
-                unichar |= (char32_t)str[i] & 0x3f;
-        }
-
-        *ret_unichar = unichar;
-
-        return 0;
-}
-
-bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
-        const char *p;
-
-        assert(str);
-
-        for (p = str; length;) {
-                int encoded_len, r;
-                char32_t val;
-
-                encoded_len = utf8_encoded_valid_unichar(p);
-                if (encoded_len < 0 ||
-                    (size_t) encoded_len > length)
-                        return false;
-
-                r = utf8_encoded_to_unichar(p, &val);
-                if (r < 0 ||
-                    unichar_is_control(val) ||
-                    (!newline && val == '\n'))
-                        return false;
-
-                length -= encoded_len;
-                p += encoded_len;
-        }
-
-        return true;
-}
-
-const char *utf8_is_valid(const char *str) {
-        const uint8_t *p;
-
-        assert(str);
-
-        for (p = (const uint8_t*) str; *p; ) {
-                int len;
-
-                len = utf8_encoded_valid_unichar((const char *)p);
-                if (len < 0)
-                        return NULL;
-
-                p += len;
-        }
-
-        return str;
-}
-
-char *utf8_escape_invalid(const char *str) {
-        char *p, *s;
-
-        assert(str);
-
-        p = s = malloc(strlen(str) * 4 + 1);
-        if (!p)
-                return NULL;
-
-        while (*str) {
-                int len;
-
-                len = utf8_encoded_valid_unichar(str);
-                if (len > 0) {
-                        s = mempcpy(s, str, len);
-                        str += len;
-                } else {
-                        s = stpcpy(s, UTF8_REPLACEMENT_CHARACTER);
-                        str += 1;
-                }
-        }
-
-        *s = '\0';
-
-        return p;
-}
-
-char *utf8_escape_non_printable(const char *str) {
-        char *p, *s;
-
-        assert(str);
-
-        p = s = malloc(strlen(str) * 4 + 1);
-        if (!p)
-                return NULL;
-
-        while (*str) {
-                int len;
-
-                len = utf8_encoded_valid_unichar(str);
-                if (len > 0) {
-                        if (utf8_is_printable(str, len)) {
-                                s = mempcpy(s, str, len);
-                                str += len;
-                        } else {
-                                while (len > 0) {
-                                        *(s++) = '\\';
-                                        *(s++) = 'x';
-                                        *(s++) = hexchar((int) *str >> 4);
-                                        *(s++) = hexchar((int) *str);
-
-                                        str += 1;
-                                        len--;
-                                }
-                        }
-                } else {
-                        s = stpcpy(s, UTF8_REPLACEMENT_CHARACTER);
-                        str += 1;
-                }
-        }
-
-        *s = '\0';
-
-        return p;
-}
-
-char *ascii_is_valid(const char *str) {
-        const char *p;
-
-        /* Check whether the string consists of valid ASCII bytes,
-         * i.e values between 0 and 127, inclusive. */
-
-        assert(str);
-
-        for (p = str; *p; p++)
-                if ((unsigned char) *p >= 128)
-                        return NULL;
-
-        return (char*) str;
-}
-
-char *ascii_is_valid_n(const char *str, size_t len) {
-        size_t i;
-
-        /* Very similar to ascii_is_valid(), but checks exactly len
-         * bytes and rejects any NULs in that range. */
-
-        assert(str);
-
-        for (i = 0; i < len; i++)
-                if ((unsigned char) str[i] >= 128 || str[i] == 0)
-                        return NULL;
-
-        return (char*) str;
-}
-
-/**
- * utf8_encode_unichar() - Encode single UCS-4 character as UTF-8
- * @out_utf8: output buffer of at least 4 bytes or NULL
- * @g: UCS-4 character to encode
- *
- * This encodes a single UCS-4 character as UTF-8 and writes it into @out_utf8.
- * The length of the character is returned. It is not zero-terminated! If the
- * output buffer is NULL, only the length is returned.
- *
- * Returns: The length in bytes that the UTF-8 representation does or would
- *          occupy.
- */
-size_t utf8_encode_unichar(char *out_utf8, char32_t g) {
-
-        if (g < (1 << 7)) {
-                if (out_utf8)
-                        out_utf8[0] = g & 0x7f;
-                return 1;
-        } else if (g < (1 << 11)) {
-                if (out_utf8) {
-                        out_utf8[0] = 0xc0 | ((g >> 6) & 0x1f);
-                        out_utf8[1] = 0x80 | (g & 0x3f);
-                }
-                return 2;
-        } else if (g < (1 << 16)) {
-                if (out_utf8) {
-                        out_utf8[0] = 0xe0 | ((g >> 12) & 0x0f);
-                        out_utf8[1] = 0x80 | ((g >> 6) & 0x3f);
-                        out_utf8[2] = 0x80 | (g & 0x3f);
-                }
-                return 3;
-        } else if (g < (1 << 21)) {
-                if (out_utf8) {
-                        out_utf8[0] = 0xf0 | ((g >> 18) & 0x07);
-                        out_utf8[1] = 0x80 | ((g >> 12) & 0x3f);
-                        out_utf8[2] = 0x80 | ((g >> 6) & 0x3f);
-                        out_utf8[3] = 0x80 | (g & 0x3f);
-                }
-                return 4;
-        }
-
-        return 0;
-}
-
-char *utf16_to_utf8(const void *s, size_t length) {
-        const uint8_t *f;
-        char *r, *t;
-
-        r = new(char, (length * 4 + 1) / 2 + 1);
-        if (!r)
-                return NULL;
-
-        f = s;
-        t = r;
-
-        while (f < (const uint8_t*) s + length) {
-                char16_t w1, w2;
-
-                /* see RFC 2781 section 2.2 */
-
-                w1 = f[1] << 8 | f[0];
-                f += 2;
-
-                if (!utf16_is_surrogate(w1)) {
-                        t += utf8_encode_unichar(t, w1);
-
-                        continue;
-                }
-
-                if (utf16_is_trailing_surrogate(w1))
-                        continue;
-                else if (f >= (const uint8_t*) s + length)
-                        break;
-
-                w2 = f[1] << 8 | f[0];
-                f += 2;
-
-                if (!utf16_is_trailing_surrogate(w2)) {
-                        f -= 2;
-                        continue;
-                }
-
-                t += utf8_encode_unichar(t, utf16_surrogate_pair_to_unichar(w1, w2));
-        }
-
-        *t = 0;
-        return r;
-}
-
-/* expected size used to encode one unicode char */
-static int utf8_unichar_to_encoded_len(char32_t unichar) {
-
-        if (unichar < 0x80)
-                return 1;
-        if (unichar < 0x800)
-                return 2;
-        if (unichar < 0x10000)
-                return 3;
-        if (unichar < 0x200000)
-                return 4;
-        if (unichar < 0x4000000)
-                return 5;
-
-        return 6;
-}
-
-/* validate one encoded unicode char and return its length */
-int utf8_encoded_valid_unichar(const char *str) {
-        int len, i, r;
-        char32_t unichar;
-
-        assert(str);
-
-        len = utf8_encoded_expected_len(str);
-        if (len == 0)
-                return -EINVAL;
-
-        /* ascii is valid */
-        if (len == 1)
-                return 1;
-
-        /* check if expected encoded chars are available */
-        for (i = 0; i < len; i++)
-                if ((str[i] & 0x80) != 0x80)
-                        return -EINVAL;
-
-        r = utf8_encoded_to_unichar(str, &unichar);
-        if (r < 0)
-                return r;
-
-        /* check if encoded length matches encoded value */
-        if (utf8_unichar_to_encoded_len(unichar) != len)
-                return -EINVAL;
-
-        /* check if value has valid range */
-        if (!unichar_is_valid(unichar))
-                return -EINVAL;
-
-        return len;
-}
-
-size_t utf8_n_codepoints(const char *str) {
-        size_t n = 0;
-
-        /* Returns the number of UTF-8 codepoints in this string, or (size_t) -1 if the string is not valid UTF-8. */
-
-        while (*str != 0) {
-                int k;
-
-                k = utf8_encoded_valid_unichar(str);
-                if (k < 0)
-                        return (size_t) -1;
-
-                str += k;
-                n++;
-        }
-
-        return n;
-}
-
-#if 0 /* NM_IGNORED */
-size_t utf8_console_width(const char *str) {
-        size_t n = 0;
-
-        /* Returns the approximate width a string will take on screen when printed on a character cell
-         * terminal/console. */
-
-        while (*str != 0) {
-                char32_t c;
-
-                if (utf8_encoded_to_unichar(str, &c) < 0)
-                        return (size_t) -1;
-
-                str = utf8_next_char(str);
-
-                n += unichar_iswide(c) ? 2 : 1;
-        }
-
-        return n;
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/utf8.h b/src/systemd/src/basic/utf8.h
deleted file mode 100644
index f37f87ff..00000000
--- a/src/systemd/src/basic/utf8.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#if 0 /* NM_IGNORED */
-#include <uchar.h>
-#endif /* NM_IGNORED */
-
-#include "macro.h"
-#include "missing.h"
-
-#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
-#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
-
-bool unichar_is_valid(char32_t c);
-
-const char *utf8_is_valid(const char *s) _pure_;
-char *ascii_is_valid(const char *s) _pure_;
-char *ascii_is_valid_n(const char *str, size_t len);
-
-bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_;
-#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true)
-
-char *utf8_escape_invalid(const char *s);
-char *utf8_escape_non_printable(const char *str);
-
-size_t utf8_encode_unichar(char *out_utf8, char32_t g);
-char *utf16_to_utf8(const void *s, size_t length);
-
-int utf8_encoded_valid_unichar(const char *str);
-int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar);
-
-static inline bool utf16_is_surrogate(char16_t c) {
-        return (0xd800 <= c && c <= 0xdfff);
-}
-
-static inline bool utf16_is_trailing_surrogate(char16_t c) {
-        return (0xdc00 <= c && c <= 0xdfff);
-}
-
-static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) {
-                return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
-}
-
-size_t utf8_n_codepoints(const char *str);
-size_t utf8_console_width(const char *str);
diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c
deleted file mode 100644
index 2c6101ea..00000000
--- a/src/systemd/src/basic/util.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include "nm-sd-adapt.h"
-
-#include <alloca.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/prctl.h>
-#include <sys/statfs.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "btrfs-util.h"
-#include "build.h"
-#include "cgroup-util.h"
-#include "def.h"
-#include "device-nodes.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "format-util.h"
-#include "hashmap.h"
-#include "hostname-util.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "procfs-util.h"
-#include "set.h"
-#include "signal-util.h"
-#include "stat-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-#include "umask-util.h"
-#include "user-util.h"
-#include "util.h"
-#include "virt.h"
-
-#if 0 /* NM_IGNORED */
-int saved_argc = 0;
-char **saved_argv = NULL;
-static int saved_in_initrd = -1;
-#endif /* NM_IGNORED */
-
-size_t page_size(void) {
-        static thread_local size_t pgsz = 0;
-        long r;
-
-        if (_likely_(pgsz > 0))
-                return pgsz;
-
-        r = sysconf(_SC_PAGESIZE);
-        assert(r > 0);
-
-        pgsz = (size_t) r;
-        return pgsz;
-}
-
-#if 0 /* NM_IGNORED */
-bool plymouth_running(void) {
-        return access("/run/plymouth/pid", F_OK) >= 0;
-}
-
-bool display_is_local(const char *display) {
-        assert(display);
-
-        return
-                display[0] == ':' &&
-                display[1] >= '0' &&
-                display[1] <= '9';
-}
-
-bool kexec_loaded(void) {
-       _cleanup_free_ char *s = NULL;
-
-       if (read_one_line_file("/sys/kernel/kexec_loaded", &s) < 0)
-               return false;
-
-       return s[0] == '1';
-}
-
-int prot_from_flags(int flags) {
-
-        switch (flags & O_ACCMODE) {
-
-        case O_RDONLY:
-                return PROT_READ;
-
-        case O_WRONLY:
-                return PROT_WRITE;
-
-        case O_RDWR:
-                return PROT_READ|PROT_WRITE;
-
-        default:
-                return -EINVAL;
-        }
-}
-
-bool in_initrd(void) {
-        struct statfs s;
-
-        if (saved_in_initrd >= 0)
-                return saved_in_initrd;
-
-        /* We make two checks here:
-         *
-         * 1. the flag file /etc/initrd-release must exist
-         * 2. the root file system must be a memory file system
-         *
-         * The second check is extra paranoia, since misdetecting an
-         * initrd can have bad consequences due the initrd
-         * emptying when transititioning to the main systemd.
-         */
-
-        saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 &&
-                          statfs("/", &s) >= 0 &&
-                          is_temporary_fs(&s);
-
-        return saved_in_initrd;
-}
-
-void in_initrd_force(bool value) {
-        saved_in_initrd = value;
-}
-
-/* hey glibc, APIs with callbacks without a user pointer are so useless */
-void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 int (*compar) (const void *, const void *, void *), void *arg) {
-        size_t l, u, idx;
-        const void *p;
-        int comparison;
-
-        assert(!size_multiply_overflow(nmemb, size));
-
-        l = 0;
-        u = nmemb;
-        while (l < u) {
-                idx = (l + u) / 2;
-                p = (const uint8_t*) base + idx * size;
-                comparison = compar(key, p, arg);
-                if (comparison < 0)
-                        u = idx;
-                else if (comparison > 0)
-                        l = idx + 1;
-                else
-                        return (void *)p;
-        }
-        return NULL;
-}
-
-int on_ac_power(void) {
-        bool found_offline = false, found_online = false;
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-
-        d = opendir("/sys/class/power_supply");
-        if (!d)
-                return errno == ENOENT ? true : -errno;
-
-        FOREACH_DIRENT(de, d, return -errno) {
-                _cleanup_close_ int fd = -1, device = -1;
-                char contents[6];
-                ssize_t n;
-
-                device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (device < 0) {
-                        if (IN_SET(errno, ENOENT, ENOTDIR))
-                                continue;
-
-                        return -errno;
-                }
-
-                fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0) {
-                        if (errno == ENOENT)
-                                continue;
-
-                        return -errno;
-                }
-
-                n = read(fd, contents, sizeof(contents));
-                if (n < 0)
-                        return -errno;
-
-                if (n != 6 || memcmp(contents, "Mains\n", 6))
-                        continue;
-
-                safe_close(fd);
-                fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0) {
-                        if (errno == ENOENT)
-                                continue;
-
-                        return -errno;
-                }
-
-                n = read(fd, contents, sizeof(contents));
-                if (n < 0)
-                        return -errno;
-
-                if (n != 2 || contents[1] != '\n')
-                        return -EIO;
-
-                if (contents[0] == '1') {
-                        found_online = true;
-                        break;
-                } else if (contents[0] == '0')
-                        found_offline = true;
-                else
-                        return -EIO;
-        }
-
-        return found_online || !found_offline;
-}
-
-int container_get_leader(const char *machine, pid_t *pid) {
-        _cleanup_free_ char *s = NULL, *class = NULL;
-        const char *p;
-        pid_t leader;
-        int r;
-
-        assert(machine);
-        assert(pid);
-
-        if (streq(machine, ".host")) {
-                *pid = 1;
-                return 0;
-        }
-
-        if (!machine_name_is_valid(machine))
-                return -EINVAL;
-
-        p = strjoina("/run/systemd/machines/", machine);
-        r = parse_env_file(NULL, p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
-        if (r == -ENOENT)
-                return -EHOSTDOWN;
-        if (r < 0)
-                return r;
-        if (!s)
-                return -EIO;
-
-        if (!streq_ptr(class, "container"))
-                return -EIO;
-
-        r = parse_pid(s, &leader);
-        if (r < 0)
-                return r;
-        if (leader <= 1)
-                return -EIO;
-
-        *pid = leader;
-        return 0;
-}
-
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
-        _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
-        int rfd = -1;
-
-        assert(pid >= 0);
-
-        if (mntns_fd) {
-                const char *mntns;
-
-                mntns = procfs_file_alloca(pid, "ns/mnt");
-                mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (mntnsfd < 0)
-                        return -errno;
-        }
-
-        if (pidns_fd) {
-                const char *pidns;
-
-                pidns = procfs_file_alloca(pid, "ns/pid");
-                pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (pidnsfd < 0)
-                        return -errno;
-        }
-
-        if (netns_fd) {
-                const char *netns;
-
-                netns = procfs_file_alloca(pid, "ns/net");
-                netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (netnsfd < 0)
-                        return -errno;
-        }
-
-        if (userns_fd) {
-                const char *userns;
-
-                userns = procfs_file_alloca(pid, "ns/user");
-                usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (usernsfd < 0 && errno != ENOENT)
-                        return -errno;
-        }
-
-        if (root_fd) {
-                const char *root;
-
-                root = procfs_file_alloca(pid, "root");
-                rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
-                if (rfd < 0)
-                        return -errno;
-        }
-
-        if (pidns_fd)
-                *pidns_fd = pidnsfd;
-
-        if (mntns_fd)
-                *mntns_fd = mntnsfd;
-
-        if (netns_fd)
-                *netns_fd = netnsfd;
-
-        if (userns_fd)
-                *userns_fd = usernsfd;
-
-        if (root_fd)
-                *root_fd = rfd;
-
-        pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
-
-        return 0;
-}
-
-int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
-        if (userns_fd >= 0) {
-                /* Can't setns to your own userns, since then you could
-                 * escalate from non-root to root in your own namespace, so
-                 * check if namespaces equal before attempting to enter. */
-                _cleanup_free_ char *userns_fd_path = NULL;
-                int r;
-                if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
-                        return -ENOMEM;
-
-                r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
-                if (r < 0)
-                        return r;
-                if (r)
-                        userns_fd = -1;
-        }
-
-        if (pidns_fd >= 0)
-                if (setns(pidns_fd, CLONE_NEWPID) < 0)
-                        return -errno;
-
-        if (mntns_fd >= 0)
-                if (setns(mntns_fd, CLONE_NEWNS) < 0)
-                        return -errno;
-
-        if (netns_fd >= 0)
-                if (setns(netns_fd, CLONE_NEWNET) < 0)
-                        return -errno;
-
-        if (userns_fd >= 0)
-                if (setns(userns_fd, CLONE_NEWUSER) < 0)
-                        return -errno;
-
-        if (root_fd >= 0) {
-                if (fchdir(root_fd) < 0)
-                        return -errno;
-
-                if (chroot(".") < 0)
-                        return -errno;
-        }
-
-        return reset_uid_gid();
-}
-
-uint64_t physical_memory(void) {
-        _cleanup_free_ char *root = NULL, *value = NULL;
-        uint64_t mem, lim;
-        size_t ps;
-        long sc;
-        int r;
-
-        /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of
-         * memory.
-         *
-         * In order to support containers nicely that have a configured memory limit we'll take the minimum of the
-         * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */
-
-        sc = sysconf(_SC_PHYS_PAGES);
-        assert(sc > 0);
-
-        ps = page_size();
-        mem = (uint64_t) sc * (uint64_t) ps;
-
-        r = cg_get_root_path(&root);
-        if (r < 0) {
-                log_debug_errno(r, "Failed to determine root cgroup, ignoring cgroup memory limit: %m");
-                return mem;
-        }
-
-        r = cg_all_unified();
-        if (r < 0) {
-                log_debug_errno(r, "Failed to determine root unified mode, ignoring cgroup memory limit: %m");
-                return mem;
-        }
-        if (r > 0) {
-                r = cg_get_attribute("memory", root, "memory.max", &value);
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m");
-                        return mem;
-                }
-
-                if (streq(value, "max"))
-                        return mem;
-        } else {
-                r = cg_get_attribute("memory", root, "memory.limit_in_bytes", &value);
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m");
-                        return mem;
-                }
-        }
-
-        r = safe_atou64(value, &lim);
-        if (r < 0) {
-                log_debug_errno(r, "Failed to parse cgroup memory limit '%s', ignoring: %m", value);
-                return mem;
-        }
-        if (lim == UINT64_MAX)
-                return mem;
-
-        /* Make sure the limit is a multiple of our own page size */
-        lim /= ps;
-        lim *= ps;
-
-        return MIN(mem, lim);
-}
-
-uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
-        uint64_t p, m, ps, r;
-
-        assert(max > 0);
-
-        /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
-         * the result is a multiple of the page size (rounds down). */
-
-        ps = page_size();
-        assert(ps > 0);
-
-        p = physical_memory() / ps;
-        assert(p > 0);
-
-        m = p * v;
-        if (m / p != v)
-                return UINT64_MAX;
-
-        m /= max;
-
-        r = m * ps;
-        if (r / ps != m)
-                return UINT64_MAX;
-
-        return r;
-}
-
-uint64_t system_tasks_max(void) {
-
-        uint64_t a = TASKS_MAX, b = TASKS_MAX;
-        _cleanup_free_ char *root = NULL;
-        int r;
-
-        /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this
-         * limit:
-         *
-         * a) the maximum tasks value the kernel allows on this architecture
-         * b) the cgroups pids_max attribute for the system
-         * c) the kernel's configured maximum PID value
-         *
-         * And then pick the smallest of the three */
-
-        r = procfs_tasks_get_limit(&a);
-        if (r < 0)
-                log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m");
-
-        r = cg_get_root_path(&root);
-        if (r < 0)
-                log_debug_errno(r, "Failed to determine cgroup root path, ignoring: %m");
-        else {
-                _cleanup_free_ char *value = NULL;
-
-                r = cg_get_attribute("pids", root, "pids.max", &value);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to read pids.max attribute of cgroup root, ignoring: %m");
-                else if (!streq(value, "max")) {
-                        r = safe_atou64(value, &b);
-                        if (r < 0)
-                                log_debug_errno(r, "Failed to parse pids.max attribute of cgroup root, ignoring: %m");
-                }
-        }
-
-        return MIN3(TASKS_MAX,
-                    a <= 0 ? TASKS_MAX : a,
-                    b <= 0 ? TASKS_MAX : b);
-}
-
-uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
-        uint64_t t, m;
-
-        assert(max > 0);
-
-        /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
-         * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
-
-        t = system_tasks_max();
-        assert(t > 0);
-
-        m = t * v;
-        if (m / t != v) /* overflow? */
-                return UINT64_MAX;
-
-        return m / max;
-}
-
-int version(void) {
-        puts(PACKAGE_STRING "\n"
-             SYSTEMD_FEATURES);
-        return 0;
-}
-
-/* This is a direct translation of str_verscmp from boot.c */
-static bool is_digit(int c) {
-        return c >= '0' && c <= '9';
-}
-
-static int c_order(int c) {
-        if (c == 0 || is_digit(c))
-                return 0;
-
-        if ((c >= 'a') && (c <= 'z'))
-                return c;
-
-        return c + 0x10000;
-}
-
-int str_verscmp(const char *s1, const char *s2) {
-        const char *os1, *os2;
-
-        assert(s1);
-        assert(s2);
-
-        os1 = s1;
-        os2 = s2;
-
-        while (*s1 || *s2) {
-                int first;
-
-                while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) {
-                        int order;
-
-                        order = c_order(*s1) - c_order(*s2);
-                        if (order != 0)
-                                return order;
-                        s1++;
-                        s2++;
-                }
-
-                while (*s1 == '0')
-                        s1++;
-                while (*s2 == '0')
-                        s2++;
-
-                first = 0;
-                while (is_digit(*s1) && is_digit(*s2)) {
-                        if (first == 0)
-                                first = *s1 - *s2;
-                        s1++;
-                        s2++;
-                }
-
-                if (is_digit(*s1))
-                        return 1;
-                if (is_digit(*s2))
-                        return -1;
-
-                if (first != 0)
-                        return first;
-        }
-
-        return strcmp(os1, os2);
-}
-
-/* Turn off core dumps but only if we're running outside of a container. */
-void disable_coredumps(void) {
-        int r;
-
-        if (detect_container() > 0)
-                return;
-
-        r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
-        if (r < 0)
-                log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
-}
-#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h
deleted file mode 100644
index 308933ac..00000000
--- a/src/systemd/src/basic/util.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <alloca.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "format-util.h"
-#include "macro.h"
-#include "missing.h"
-#include "time-util.h"
-
-size_t page_size(void) _pure_;
-#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
-
-static inline const char* yes_no(bool b) {
-        return b ? "yes" : "no";
-}
-
-static inline const char* true_false(bool b) {
-        return b ? "true" : "false";
-}
-
-static inline const char* one_zero(bool b) {
-        return b ? "1" : "0";
-}
-
-static inline const char* enable_disable(bool b) {
-        return b ? "enable" : "disable";
-}
-
-bool plymouth_running(void);
-
-bool display_is_local(const char *display) _pure_;
-
-#define NULSTR_FOREACH(i, l)                                    \
-        for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
-
-#define NULSTR_FOREACH_PAIR(i, j, l)                             \
-        for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
-
-extern int saved_argc;
-extern char **saved_argv;
-
-bool kexec_loaded(void);
-
-int prot_from_flags(int flags) _const_;
-
-bool in_initrd(void);
-void in_initrd_force(bool value);
-
-void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 int (*compar) (const void *, const void *, void *),
-                 void *arg);
-
-/**
- * Normal bsearch requires base to be nonnull. Here were require
- * that only if nmemb > 0.
- */
-static inline void* bsearch_safe(const void *key, const void *base,
-                                 size_t nmemb, size_t size, comparison_fn_t compar) {
-        if (nmemb <= 0)
-                return NULL;
-
-        assert(base);
-        return bsearch(key, base, nmemb, size, compar);
-}
-
-/**
- * Normal qsort requires base to be nonnull. Here were require
- * that only if nmemb > 0.
- */
-static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
-        if (nmemb <= 1)
-                return;
-
-        assert(base);
-        qsort(base, nmemb, size, compar);
-}
-
-/* A wrapper around the above, but that adds typesafety: the element size is automatically derived from the type and so
- * is the prototype for the comparison function */
-#define typesafe_qsort(p, n, func)                                      \
-        ({                                                              \
-                int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
-                qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \
-        })
-
-static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void *userdata) {
-        if (nmemb <= 1)
-                return;
-
-        assert(base);
-        qsort_r(base, nmemb, size, compar, userdata);
-}
-
-/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
-static inline void memcpy_safe(void *dst, const void *src, size_t n) {
-        if (n == 0)
-                return;
-        assert(src);
-        memcpy(dst, src, n);
-}
-
-/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
-static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
-        if (n == 0)
-                return 0;
-        assert(s1);
-        assert(s2);
-        return memcmp(s1, s2, n);
-}
-
-int on_ac_power(void);
-
-#define memzero(x,l) (memset((x), 0, (l)))
-#define zero(x) (memzero(&(x), sizeof(x)))
-
-static inline void *mempset(void *s, int c, size_t n) {
-        memset(s, c, n);
-        return (uint8_t*)s + n;
-}
-
-static inline void _reset_errno_(int *saved_errno) {
-        errno = *saved_errno;
-}
-
-#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
-
-static inline int negative_errno(void) {
-        /* This helper should be used to shut up gcc if you know 'errno' is
-         * negative. Instead of "return -errno;", use "return negative_errno();"
-         * It will suppress bogus gcc warnings in case it assumes 'errno' might
-         * be 0 and thus the caller's error-handling might not be triggered. */
-        assert_return(errno > 0, -EINVAL);
-        return -errno;
-}
-
-static inline unsigned u64log2(uint64_t n) {
-#if __SIZEOF_LONG_LONG__ == 8
-        return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
-#else
-#error "Wut?"
-#endif
-}
-
-static inline unsigned u32ctz(uint32_t n) {
-#if __SIZEOF_INT__ == 4
-        return __builtin_ctz(n);
-#else
-#error "Wut?"
-#endif
-}
-
-static inline unsigned log2i(int x) {
-        assert(x > 0);
-
-        return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
-}
-
-static inline unsigned log2u(unsigned x) {
-        assert(x > 0);
-
-        return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
-}
-
-static inline unsigned log2u_round_up(unsigned x) {
-        assert(x > 0);
-
-        if (x == 1)
-                return 0;
-
-        return log2u(x - 1) + 1;
-}
-
-int container_get_leader(const char *machine, pid_t *pid);
-
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
-int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
-
-uint64_t physical_memory(void);
-uint64_t physical_memory_scale(uint64_t v, uint64_t max);
-
-uint64_t system_tasks_max(void);
-uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
-
-int version(void);
-
-int str_verscmp(const char *s1, const char *s2);
-
-void disable_coredumps(void);
diff --git a/src/systemd/src/libsystemd-network/arp-util.c b/src/systemd/src/libsystemd-network/arp-util.c
index 4fbecb54..154ba6b7 100644
--- a/src/systemd/src/libsystemd-network/arp-util.c
+++ b/src/systemd/src/libsystemd-network/arp-util.c
@@ -3,7 +3,7 @@
   Copyright © 2014 Axis Communications AB. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <linux/filter.h>
 #include <arpa/inet.h>
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c
index b1afbf00..7fc8248a 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.c
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <linux/if_infiniband.h>
 #include <net/if_arp.h>
@@ -13,13 +13,9 @@
 #include "network-internal.h"
 #include "siphash24.h"
 #include "sparse-endian.h"
+#include "stdio-util.h"
 #include "virt.h"
 
-#if 0 /* NM_IGNORED */
-#else /* NM_IGNORED */
-#include <net/if.h>
-#endif /* NM_IGNORED */
-
 #define SYSTEMD_PEN    43793
 #define HASH_KEY       SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
 #define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
@@ -123,8 +119,13 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         assert(len);
 
         r = sd_id128_get_machine(&machine_id);
-        if (r < 0)
+        if (r < 0) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+                machine_id = SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10);
+#else
                 return r;
+#endif
+        }
 
         unaligned_write_be16(&duid->type, DUID_TYPE_EN);
         unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
@@ -160,38 +161,37 @@ int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) {
 }
 #endif
 
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) {
+int dhcp_identifier_set_iaid(
+                int ifindex,
+                const uint8_t *mac,
+                size_t mac_len,
+                bool legacy_unstable_byteorder,
+                void *_id) {
 #if 0 /* NM_IGNORED */
         /* name is a pointer to memory in the sd_device struct, so must
          * have the same scope */
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
-#else /* NM_IGNORED */
-        char name_buf[IF_NAMESIZE];
-#endif /* NM_IGNORED */
         const char *name = NULL;
         uint64_t id;
+        uint32_t id32;
 
-#if 0 /* NM_IGNORED */
         if (detect_container() <= 0) {
                 /* not in a container, udev will be around */
-                char ifindex_str[2 + DECIMAL_STR_MAX(int)];
-                int initialized, r;
+                char ifindex_str[1 + DECIMAL_STR_MAX(int)];
+                int r;
 
-                sprintf(ifindex_str, "n%d", ifindex);
+                xsprintf(ifindex_str, "n%d", ifindex);
                 if (sd_device_new_from_device_id(&device, ifindex_str) >= 0) {
-                        r = sd_device_get_is_initialized(device, &initialized);
+                        r = sd_device_get_is_initialized(device);
                         if (r < 0)
                                 return r;
-                        if (!initialized)
+                        if (r == 0)
                                 /* not yet ready */
                                 return -EBUSY;
 
                         name = net_get_name(device);
                 }
         }
-#else /* NM_IGNORED */
-        name = if_indextoname(ifindex, name_buf);
-#endif /* NM_IGNORED */
 
         if (name)
                 id = siphash24(name, strlen(name), HASH_KEY.bytes);
@@ -199,10 +199,23 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
                 /* fall back to MAC address if no predictable name available */
                 id = siphash24(mac, mac_len, HASH_KEY.bytes);
 
-        id = htole64(id);
+        id32 = (id & 0xffffffff) ^ (id >> 32);
 
-        /* fold into 32 bits */
-        unaligned_write_be32(_id, (id & 0xffffffff) ^ (id >> 32));
+        if (legacy_unstable_byteorder)
+                /* for historical reasons (a bug), the bits were swapped and thus
+                 * the result was endianness dependent. Preserve that behavior. */
+                id32 = __bswap_32(id32);
+        else
+                /* the fixed behavior returns a stable byte order. Since LE is expected
+                 * to be more common, swap the bytes on LE to give the same as legacy
+                 * behavior. */
+                id32 = be32toh(id32);
 
+        unaligned_write_ne32(_id, id32);
         return 0;
+#else /* NM_IGNORED */
+        /* for NetworkManager, we don't use this function and we should never call here.
+         * This got replaced by nm_utils_create_dhcp_iaid(). */
+        g_return_val_if_reached (-EINVAL);
+#endif /* NM_IGNORED */
 }
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.h b/src/systemd/src/libsystemd-network/dhcp-identifier.h
index e6834039..b3115125 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.h
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.h
@@ -57,4 +57,4 @@ int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *add
 int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
 int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len);
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
+int dhcp_identifier_set_iaid(int ifindex, const uint8_t *mac, size_t mac_len, bool legacy_unstable_byteorder, void *_id);
diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
index 9d245a90..122042ab 100644
--- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
@@ -41,7 +41,6 @@ struct sd_dhcp_lease {
         /* each 0 if unset */
         be32_t address;
         be32_t server_address;
-        be32_t router;
         be32_t next_server;
 
         bool have_subnet_mask;
@@ -50,6 +49,9 @@ struct sd_dhcp_lease {
         bool have_broadcast;
         be32_t broadcast;
 
+        struct in_addr *router;
+        size_t router_size;
+
         struct in_addr *dns;
         size_t dns_size;
 
diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c
index 80e9577c..810a2633 100644
--- a/src/systemd/src/libsystemd-network/dhcp-network.c
+++ b/src/systemd/src/libsystemd-network/dhcp-network.c
@@ -3,9 +3,8 @@
   Copyright © 2013 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -52,12 +51,16 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
                 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)),  /* A <- DHCP header type */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0),                   /* header type == arp_type ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
-                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)),   /* A <- MAC address length */
-                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0),                  /* address length == dhcp_hlen ? */
-                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)),    /* A <- client identifier */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0),                        /* client identifier == xid ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)),   /* A <- MAC address length */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0),                  /* address length == dhcp_hlen ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+
+                /* We only support MAC address length to be either 0 or 6 (ETH_ALEN). Optionally
+                 * compare chaddr for ETH_ALEN bytes. */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETH_ALEN, 0, 12),                                  /* A (the MAC address length) == ETH_ALEN ? */
                 BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be32(&eth_mac->ether_addr_octet[0])),        /* A <- 4 bytes of client's MAC */
                 BPF_STMT(BPF_MISC + BPF_TAX, 0),                                                       /* X <- A */
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)),                 /* A <- 4 bytes of MAC from dhcp.chaddr */
@@ -70,6 +73,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
                 BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                                /* A xor X */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                                          /* A == 0 ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                                          /* ignore */
+
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)),  /* A <- DHCP magic cookie */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0),          /* cookie == DHCP magic cookie ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
@@ -80,7 +84,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
                 .filter = filter
         };
         _cleanup_close_ int s = -1;
-        int r, on = 1;
+        int r;
 
         assert(ifindex > 0);
         assert(link);
@@ -89,9 +93,9 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
         if (s < 0)
                 return -errno;
 
-        r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on));
+        r = setsockopt_int(s, SOL_PACKET, PACKET_AUXDATA, true);
         if (r < 0)
-                return -errno;
+                return r;
 
         r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
         if (r < 0)
@@ -151,19 +155,19 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
         };
         _cleanup_close_ int s = -1;
         char ifname[IF_NAMESIZE] = "";
-        int r, on = 1, tos = IPTOS_CLASS_CS6;
+        int r;
 
         s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
         if (s < 0)
                 return -errno;
 
-        r = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
+        r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
         if (r < 0)
-                return -errno;
+                return r;
 
-        r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+        r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
         if (r < 0)
-                return -errno;
+                return r;
 
         if (ifindex > 0) {
                 if (if_indextoname(ifindex, ifname) == 0)
@@ -175,18 +179,18 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
         }
 
         if (address == INADDR_ANY) {
-                r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
+                r = setsockopt_int(s, IPPROTO_IP, IP_PKTINFO, true);
                 if (r < 0)
-                        return -errno;
+                        return r;
 
-                r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+                r = setsockopt_int(s, SOL_SOCKET, SO_BROADCAST, true);
                 if (r < 0)
-                        return -errno;
+                        return r;
 
         } else {
-                r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
+                r = setsockopt_int(s, IPPROTO_IP, IP_FREEBIND, true);
                 if (r < 0)
-                        return -errno;
+                        return r;
         }
 
         r = bind(s, &src.sa, sizeof(src.in));
diff --git a/src/systemd/src/libsystemd-network/dhcp-option.c b/src/systemd/src/libsystemd-network/dhcp-option.c
index 4a4f7de0..c5fbe749 100644
--- a/src/systemd/src/libsystemd-network/dhcp-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp-option.c
@@ -3,9 +3,8 @@
   Copyright © 2013 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/systemd/src/libsystemd-network/dhcp-packet.c b/src/systemd/src/libsystemd-network/dhcp-packet.c
index 8f8acb0d..91e8a54e 100644
--- a/src/systemd/src/libsystemd-network/dhcp-packet.c
+++ b/src/systemd/src/libsystemd-network/dhcp-packet.c
@@ -3,9 +3,8 @@
   Copyright © 2013 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
 #include <string.h>
@@ -108,70 +107,62 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui
 
         /* IP */
 
-        if (packet->ip.version != IPVERSION) {
-                log_debug("ignoring packet: not IPv4");
-                return -EINVAL;
-        }
+        if (packet->ip.version != IPVERSION)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: not IPv4");
 
-        if (packet->ip.ihl < 5) {
-                log_debug("ignoring packet: IPv4 IHL (%u words) invalid",
-                          packet->ip.ihl);
-                return -EINVAL;
-        }
+        if (packet->ip.ihl < 5)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: IPv4 IHL (%u words) invalid",
+                                       packet->ip.ihl);
 
         hdrlen = packet->ip.ihl * 4;
-        if (hdrlen < 20) {
-                log_debug("ignoring packet: IPv4 IHL (%zu bytes) "
-                          "smaller than minimum (20 bytes)", hdrlen);
-                return -EINVAL;
-        }
-
-        if (len < hdrlen) {
-                log_debug("ignoring packet: packet (%zu bytes) "
-                          "smaller than expected (%zu) by IP header", len,
-                          hdrlen);
-                return -EINVAL;
-        }
+        if (hdrlen < 20)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: IPv4 IHL (%zu bytes) "
+                                       "smaller than minimum (20 bytes)",
+                                       hdrlen);
+
+        if (len < hdrlen)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: packet (%zu bytes) "
+                                       "smaller than expected (%zu) by IP header",
+                                       len, hdrlen);
 
         /* UDP */
 
-        if (packet->ip.protocol != IPPROTO_UDP) {
-                log_debug("ignoring packet: not UDP");
-                return -EINVAL;
-        }
+        if (packet->ip.protocol != IPPROTO_UDP)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: not UDP");
 
-        if (len < hdrlen + be16toh(packet->udp.len)) {
-                log_debug("ignoring packet: packet (%zu bytes) "
-                          "smaller than expected (%zu) by UDP header", len,
-                          hdrlen + be16toh(packet->udp.len));
-                return -EINVAL;
-        }
+        if (len < hdrlen + be16toh(packet->udp.len))
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: packet (%zu bytes) "
+                                       "smaller than expected (%zu) by UDP header",
+                                       len, hdrlen + be16toh(packet->udp.len));
 
-        if (be16toh(packet->udp.dest) != port) {
-                log_debug("ignoring packet: to port %u, which "
-                          "is not the DHCP client port (%u)",
-                          be16toh(packet->udp.dest), port);
-                return -EINVAL;
-        }
+        if (be16toh(packet->udp.dest) != port)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: to port %u, which "
+                                       "is not the DHCP client port (%u)",
+                                       be16toh(packet->udp.dest), port);
 
         /* checksums - computing these is relatively expensive, so only do it
            if all the other checks have passed
          */
 
-        if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen)) {
-                log_debug("ignoring packet: invalid IP checksum");
-                return -EINVAL;
-        }
+        if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen))
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "ignoring packet: invalid IP checksum");
 
         if (checksum && packet->udp.check) {
                 packet->ip.check = packet->udp.len;
                 packet->ip.ttl = 0;
 
                 if (dhcp_packet_checksum((uint8_t*)&packet->ip.ttl,
-                                  be16toh(packet->udp.len) + 12)) {
-                        log_debug("ignoring packet: invalid UDP checksum");
-                        return -EINVAL;
-                }
+                                  be16toh(packet->udp.len) + 12))
+                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "ignoring packet: invalid UDP checksum");
         }
 
         return 0;
diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h
index 06e2e532..157fc0aa 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h
@@ -73,8 +73,6 @@ struct DHCP6IA {
                 struct ia_pd ia_pd;
                 struct ia_ta ia_ta;
         };
-        sd_event_source *timeout_t1;
-        sd_event_source *timeout_t2;
 
         LIST_HEAD(DHCP6Address, addresses);
 };
@@ -86,8 +84,8 @@ typedef struct DHCP6IA DHCP6IA;
 
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia);
-int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd);
+int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
+int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd);
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                        size_t *optlen, uint8_t **optvalue);
diff --git a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
index ff0b0f00..e004f48b 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
@@ -37,7 +37,6 @@ struct sd_dhcp6_lease {
         size_t ntp_fqdn_count;
 };
 
-int dhcp6_lease_clear_timers(DHCP6IA *ia);
 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia);
 
@@ -50,6 +49,7 @@ int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease);
 int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
 
 int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
+int dhcp6_lease_get_pd_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
 
 int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
 int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
diff --git a/src/systemd/src/libsystemd-network/dhcp6-network.c b/src/systemd/src/libsystemd-network/dhcp6-network.c
index 98aa6261..d786756e 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-network.c
+++ b/src/systemd/src/libsystemd-network/dhcp6-network.c
@@ -3,9 +3,8 @@
   Copyright © 2014 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <netinet/in.h>
 #include <netinet/ip6.h>
 #include <stdio.h>
@@ -27,7 +26,7 @@ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
                 .in6.sin6_scope_id = index,
         };
         _cleanup_close_ int s = -1;
-        int r, off = 0, on = 1;
+        int r;
 
         assert(index > 0);
         assert(local_address);
@@ -38,17 +37,17 @@ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
         if (s < 0)
                 return -errno;
 
-        r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+        r = setsockopt_int(s, IPPROTO_IPV6, IPV6_V6ONLY, true);
         if (r < 0)
-                return -errno;
+                return r;
 
-        r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off));
+        r = setsockopt_int(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, false);
         if (r < 0)
-                return -errno;
+                return r;
 
-        r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+        r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
         if (r < 0)
-                return -errno;
+                return r;
 
         r = bind(s, &src.sa, sizeof(src.in6));
         if (r < 0)
diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
index 22970443..3d5abe64 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
@@ -3,9 +3,8 @@
   Copyright © 2014-2015 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <netinet/in.h>
 #include <string.h>
 
@@ -39,9 +38,9 @@ typedef struct DHCP6PDPrefixOption {
         uint8_t options[];
 } _packed_ DHCP6PDPrefixOption;
 
-#define DHCP6_OPTION_IA_NA_LEN                  (sizeof(struct ia_na))
-#define DHCP6_OPTION_IA_PD_LEN                  (sizeof(struct ia_pd))
-#define DHCP6_OPTION_IA_TA_LEN                  (sizeof(struct ia_ta))
+#define DHCP6_OPTION_IA_NA_LEN (sizeof(struct ia_na))
+#define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
+#define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
 
 static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
                              size_t optlen) {
@@ -51,14 +50,14 @@ static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
         assert_return(*buf, -EINVAL);
         assert_return(buflen, -EINVAL);
 
-        if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option))
+        if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data))
                 return -ENOBUFS;
 
         option->code = htobe16(optcode);
         option->len = htobe16(optlen);
 
-        *buf += sizeof(DHCP6Option);
-        *buflen -= sizeof(DHCP6Option);
+        *buf += offsetof(DHCP6Option, data);
+        *buflen -= offsetof(DHCP6Option, data);
 
         return 0;
 }
@@ -81,14 +80,17 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
         return 0;
 }
 
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
+int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
         uint16_t len;
         uint8_t *ia_hdr;
         size_t iaid_offset, ia_buflen, ia_addrlen = 0;
         DHCP6Address *addr;
         int r;
 
-        assert_return(buf && *buf && buflen && ia, -EINVAL);
+        assert_return(buf, -EINVAL);
+        assert_return(*buf, -EINVAL);
+        assert_return(buflen, -EINVAL);
+        assert_return(ia, -EINVAL);
 
         switch (ia->type) {
         case SD_DHCP6_OPTION_IA_NA:
@@ -111,8 +113,8 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
         ia_hdr = *buf;
         ia_buflen = *buflen;
 
-        *buf += sizeof(DHCP6Option);
-        *buflen -= sizeof(DHCP6Option);
+        *buf += offsetof(DHCP6Option, data);
+        *buflen -= offsetof(DHCP6Option, data);
 
         memcpy(*buf, (char*) ia + iaid_offset, len);
 
@@ -130,7 +132,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
                 *buf += sizeof(addr->iaaddr);
                 *buflen -= sizeof(addr->iaaddr);
 
-                ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr);
+                ia_addrlen += offsetof(DHCP6Option, data) + sizeof(addr->iaaddr);
         }
 
         r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
@@ -167,7 +169,7 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
         return r;
 }
 
-int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd) {
+int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd) {
         DHCP6Option *option = (DHCP6Option *)buf;
         size_t i = sizeof(*option) + sizeof(pd->ia_pd);
         DHCP6Address *prefix;
@@ -212,7 +214,7 @@ static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, si
         assert_return(optcode, -EINVAL);
         assert_return(optlen, -EINVAL);
 
-        if (*buflen < sizeof(DHCP6Option))
+        if (*buflen < offsetof(DHCP6Option, data))
                 return -ENOMSG;
 
         len = be16toh(option->len);
@@ -253,7 +255,7 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
         DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option;
 
         if (len < sizeof(DHCP6StatusOption) ||
-            be16toh(option->len) + sizeof(DHCP6Option) < sizeof(DHCP6StatusOption))
+            be16toh(option->len) + offsetof(DHCP6Option, data) < sizeof(DHCP6StatusOption))
                 return -ENOBUFS;
 
         return be16toh(statusopt->status);
@@ -266,7 +268,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
         uint32_t lt_valid, lt_pref;
         int r;
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*addr_option))
+        if (be16toh(option->len) + offsetof(DHCP6Option, data) < sizeof(*addr_option))
                 return -ENOBUFS;
 
         lt_valid = be32toh(addr_option->iaaddr.lifetime_valid);
@@ -279,8 +281,8 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
                 return 0;
         }
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*addr_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*addr_option));
+        if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) {
+                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -306,7 +308,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
         uint32_t lt_valid, lt_pref;
         int r;
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*pdprefix_option))
+        if (be16toh(option->len) + offsetof(DHCP6Option, data) < sizeof(*pdprefix_option))
                 return -ENOBUFS;
 
         lt_valid = be32toh(pdprefix_option->iapdprefix.lifetime_valid);
@@ -319,8 +321,8 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
                 return 0;
         }
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*pdprefix_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*pdprefix_option));
+        if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) {
+                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -356,10 +358,8 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
         switch (iatype) {
         case SD_DHCP6_OPTION_IA_NA:
 
-                if (len < DHCP6_OPTION_IA_NA_LEN) {
-                        r = -ENOBUFS;
-                        goto error;
-                }
+                if (len < DHCP6_OPTION_IA_NA_LEN)
+                        return -ENOBUFS;
 
                 iaaddr_offset = DHCP6_OPTION_IA_NA_LEN;
                 memcpy(&ia->ia_na, iaoption->data, sizeof(ia->ia_na));
@@ -370,18 +370,15 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
                 if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
                         log_dhcp6_client(client, "IA NA T1 %ds > T2 %ds",
                                          lt_t1, lt_t2);
-                        r = -EINVAL;
-                        goto error;
+                        return -EINVAL;
                 }
 
                 break;
 
         case SD_DHCP6_OPTION_IA_PD:
 
-                if (len < sizeof(ia->ia_pd)) {
-                        r = -ENOBUFS;
-                        goto error;
-                }
+                if (len < sizeof(ia->ia_pd))
+                        return -ENOBUFS;
 
                 iaaddr_offset = sizeof(ia->ia_pd);
                 memcpy(&ia->ia_pd, iaoption->data, sizeof(ia->ia_pd));
@@ -392,17 +389,14 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
                 if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
                         log_dhcp6_client(client, "IA PD T1 %ds > T2 %ds",
                                          lt_t1, lt_t2);
-                        r = -EINVAL;
-                        goto error;
+                        return -EINVAL;
                 }
 
                 break;
 
         case SD_DHCP6_OPTION_IA_TA:
-                if (len < DHCP6_OPTION_IA_TA_LEN) {
-                        r = -ENOBUFS;
-                        goto error;
-                }
+                if (len < DHCP6_OPTION_IA_TA_LEN)
+                        return -ENOBUFS;
 
                 iaaddr_offset = DHCP6_OPTION_IA_TA_LEN;
                 memcpy(&ia->ia_ta.id, iaoption->data, sizeof(ia->ia_ta));
@@ -410,8 +404,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
                 break;
 
         default:
-                r = -ENOMSG;
-                goto error;
+                return -ENOMSG;
         }
 
         ia->type = iatype;
@@ -420,10 +413,8 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
         while (i < len) {
                 DHCP6Option *option = (DHCP6Option *)&iaoption->data[i];
 
-                if (len < i + sizeof(*option) || len < i + sizeof(*option) + be16toh(option->len)) {
-                        r = -ENOBUFS;
-                        goto error;
-                }
+                if (len < i + sizeof(*option) || len < i + sizeof(*option) + be16toh(option->len))
+                        return -ENOBUFS;
 
                 opt = be16toh(option->code);
                 optlen = be16toh(option->len);
@@ -433,13 +424,12 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
 
                         if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) {
                                 log_dhcp6_client(client, "IA Address option not in IA NA or TA option");
-                                r = -EINVAL;
-                                goto error;
+                                return -EINVAL;
                         }
 
                         r = dhcp6_option_parse_address(option, ia, &lt_valid);
                         if (r < 0)
-                                goto error;
+                                return r;
 
                         if (lt_valid < lt_min)
                                 lt_min = lt_valid;
@@ -450,13 +440,12 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
 
                         if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) {
                                 log_dhcp6_client(client, "IA PD Prefix option not in IA PD option");
-                                r = -EINVAL;
-                                goto error;
+                                return -EINVAL;
                         }
 
                         r = dhcp6_option_parse_pdprefix(option, ia, &lt_valid);
                         if (r < 0)
-                                goto error;
+                                return r;
 
                         if (lt_valid < lt_min)
                                 lt_min = lt_valid;
@@ -465,17 +454,14 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
 
                 case SD_DHCP6_OPTION_STATUS_CODE:
 
-                        status = dhcp6_option_parse_status(option, optlen + sizeof(DHCP6Option));
-                        if (status < 0) {
-                                r = status;
-                                goto error;
-                        }
+                        status = dhcp6_option_parse_status(option, optlen + offsetof(DHCP6Option, data));
+                        if (status < 0)
+                                return status;
                         if (status > 0) {
                                 log_dhcp6_client(client, "IA status %d",
                                                  status);
 
-                                r = -EINVAL;
-                                goto error;
+                                return -EINVAL;
                         }
 
                         break;
@@ -519,8 +505,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
                 break;
         }
 
-error:
-        return r;
+        return 0;
 }
 
 int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h
index 328d51f8..88b54933 100644
--- a/src/systemd/src/libsystemd-network/lldp-internal.h
+++ b/src/systemd/src/libsystemd-network/lldp-internal.h
@@ -34,3 +34,6 @@ struct sd_lldp {
 
 #define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
 #define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
+
+const char* lldp_event_to_string(sd_lldp_event e) _const_;
+sd_lldp_event lldp_event_from_string(const char *s) _pure_;
diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.c b/src/systemd/src/libsystemd-network/lldp-neighbor.c
index cd9358a4..bbe7bf9d 100644
--- a/src/systemd/src/libsystemd-network/lldp-neighbor.c
+++ b/src/systemd/src/libsystemd-network/lldp-neighbor.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include "alloc-util.h"
 #include "escape.h"
@@ -9,40 +9,24 @@
 #include "in-addr-util.h"
 #include "lldp-internal.h"
 #include "lldp-neighbor.h"
+#include "missing.h"
 #include "unaligned.h"
+#include "util.h"
 
-static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) {
-        const LLDPNeighborID *id = p;
-
+static void lldp_neighbor_id_hash_func(const LLDPNeighborID *id, struct siphash *state) {
         siphash24_compress(id->chassis_id, id->chassis_id_size, state);
         siphash24_compress(&id->chassis_id_size, sizeof(id->chassis_id_size), state);
         siphash24_compress(id->port_id, id->port_id_size, state);
         siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state);
 }
 
-static int lldp_neighbor_id_compare_func(const void *a, const void *b) {
-        const LLDPNeighborID *x = a, *y = b;
-        int r;
-
-        r = memcmp(x->chassis_id, y->chassis_id, MIN(x->chassis_id_size, y->chassis_id_size));
-        if (r != 0)
-                return r;
-
-        r = CMP(x->chassis_id_size, y->chassis_id_size);
-        if (r != 0)
-                return r;
-
-        r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size));
-        if (r != 0)
-                return r;
-
-        return CMP(x->port_id_size, y->port_id_size);
+int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y) {
+        return memcmp_nn(x->chassis_id, x->chassis_id_size, y->chassis_id, y->chassis_id_size)
+            ?: memcmp_nn(x->port_id, x->port_id_size, y->port_id, y->port_id_size);
 }
 
-const struct hash_ops lldp_neighbor_id_hash_ops = {
-        .hash = lldp_neighbor_id_hash_func,
-        .compare = lldp_neighbor_id_compare_func
-};
+DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(lldp_neighbor_hash_ops, LLDPNeighborID, lldp_neighbor_id_hash_func, lldp_neighbor_id_compare_func,
+                                      sd_lldp_neighbor, lldp_neighbor_unlink);
 
 int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
         const sd_lldp_neighbor *x = a, *y = b;
@@ -100,7 +84,12 @@ sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n) {
         if (!n->lldp)
                 return NULL;
 
-        assert_se(hashmap_remove(n->lldp->neighbor_by_id, &n->id) == n);
+        /* Only remove the neighbor object from the hash table if it's in there, don't complain if it isn't. This is
+         * because we are used as destructor call for hashmap_clear() and thus sometimes are called to de-register
+         * ourselves from the hashtable and sometimes are called after we already are de-registered. */
+
+        (void) hashmap_remove_value(n->lldp->neighbor_by_id, &n->id, n);
+
         assert_se(prioq_remove(n->lldp->neighbor_by_expiry, n, &n->prioq_idx) >= 0);
 
         n->lldp = NULL;
@@ -704,7 +693,7 @@ _public_ int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type) {
         return type == k;
 }
 
-_public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], uint8_t *subtype) {
+_public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t *subtype) {
         const uint8_t *d;
         size_t length;
         int r;
@@ -733,7 +722,7 @@ _public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], u
         return 0;
 }
 
-_public_ int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[3], uint8_t subtype) {
+_public_ int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t subtype) {
         uint8_t k[3], st;
         int r;
 
diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.h b/src/systemd/src/libsystemd-network/lldp-neighbor.h
index 494bc517..62dbff42 100644
--- a/src/systemd/src/libsystemd-network/lldp-neighbor.h
+++ b/src/systemd/src/libsystemd-network/lldp-neighbor.h
@@ -80,7 +80,8 @@ static inline void* LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor *n) {
         return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2;
 }
 
-extern const struct hash_ops lldp_neighbor_id_hash_ops;
+extern const struct hash_ops lldp_neighbor_hash_ops;
+int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y);
 int lldp_neighbor_prioq_compare_func(const void *a, const void *b);
 
 sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n);
diff --git a/src/systemd/src/libsystemd-network/lldp-network.c b/src/systemd/src/libsystemd-network/lldp-network.c
index db779aaa..5ba9f081 100644
--- a/src/systemd/src/libsystemd-network/lldp-network.c
+++ b/src/systemd/src/libsystemd-network/lldp-network.c
@@ -1,12 +1,13 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <linux/filter.h>
 #include <netinet/if_ether.h>
 
 #include "fd-util.h"
 #include "lldp-network.h"
+#include "missing.h"
 #include "socket-util.h"
 
 int lldp_network_bind_raw_socket(int ifindex) {
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 57a59030..f85db47b 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <arpa/inet.h>
 #include <linux/if.h>
@@ -12,6 +12,7 @@
 #include "alloc-util.h"
 #include "condition.h"
 #include "conf-parser.h"
+#include "device-util.h"
 #include "dhcp-lease-internal.h"
 #include "ether-addr-util.h"
 #include "hexdecoct.h"
@@ -43,31 +44,35 @@ const char *net_get_name(sd_device *device) {
 
 int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
         size_t l, sz = 0;
-        const char *name = NULL;
+        const char *name;
         int r;
         uint8_t *v;
 
         assert(device);
 
+        /* net_get_name() will return one of the device names based on stable information about the
+         * device. If this is not available, we fall back to using the device name. */
         name = net_get_name(device);
         if (!name)
-                return -ENOENT;
+                (void) sd_device_get_sysname(device, &name);
+        if (!name)
+                return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA),
+                                              "No stable identifying information found");
 
+        log_device_debug(device, "Using \"%s\" as stable identifying information", name);
         l = strlen(name);
         sz = sizeof(sd_id128_t) + l;
-        v = alloca(sz);
+        v = newa(uint8_t, sz);
 
-        /* fetch some persistent data unique to this machine */
+        /* Fetch some persistent data unique to this machine */
         r = sd_id128_get_machine((sd_id128_t*) v);
         if (r < 0)
                  return r;
         memcpy(v + sizeof(sd_id128_t), name, l);
 
-        /* Let's hash the machine ID plus the device name. We
-        * use a fixed, but originally randomly created hash
-        * key here. */
+        /* Let's hash the machine ID plus the device name. We use
+         * a fixed, but originally randomly created hash key here. */
         *result = htole64(siphash24(v, sz, HASH_KEY.bytes));
-
         return 0;
 }
 
@@ -105,7 +110,6 @@ bool net_match_config(Set *match_mac,
                       Condition *match_arch,
                       const struct ether_addr *dev_mac,
                       const char *dev_path,
-                      const char *dev_parent_driver,
                       const char *dev_driver,
                       const char *dev_type,
                       const char *dev_name) {
@@ -258,11 +262,10 @@ int config_parse_ifalias(const char *unit,
                 return 0;
         }
 
-        free(*s);
-        if (*n)
-                *s = TAKE_PTR(n);
+        if (isempty(n))
+                *s = mfree(*s);
         else
-                *s = NULL;
+                free_and_replace(*s, n);
 
         return 0;
 }
@@ -297,7 +300,7 @@ int config_parse_hwaddr(const char *unit,
                 return 0;
         }
 
-        *hwaddr = TAKE_PTR(n);
+        free_and_replace(*hwaddr, n);
 
         return 0;
 }
@@ -375,36 +378,6 @@ int config_parse_hwaddrs(const char *unit,
         return 0;
 }
 
-int config_parse_iaid(const char *unit,
-                      const char *filename,
-                      unsigned line,
-                      const char *section,
-                      unsigned section_line,
-                      const char *lvalue,
-                      int ltype,
-                      const char *rvalue,
-                      void *data,
-                      void *userdata) {
-        uint32_t iaid;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        r = safe_atou32(rvalue, &iaid);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Unable to read IAID, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        *((uint32_t *)data) = iaid;
-
-        return 0;
-}
-
 int config_parse_bridge_port_priority(
                 const char *unit,
                 const char *filename,
@@ -444,16 +417,33 @@ int config_parse_bridge_port_priority(
 }
 #endif /* NM_IGNORED */
 
-void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
-        unsigned i;
+size_t serialize_in_addrs(FILE *f,
+                          const struct in_addr *addresses,
+                          size_t size,
+                          bool with_leading_space,
+                          bool (*predicate)(const struct in_addr *addr)) {
+        size_t count;
+        size_t i;
 
         assert(f);
         assert(addresses);
-        assert(size);
 
-        for (i = 0; i < size; i++)
-                fprintf(f, "%s%s", inet_ntoa(addresses[i]),
-                        (i < (size - 1)) ? " ": "");
+        count = 0;
+
+        for (i = 0; i < size; i++) {
+                char sbuf[INET_ADDRSTRLEN];
+
+                if (predicate && !predicate(&addresses[i]))
+                        continue;
+                if (with_leading_space)
+                        fputc(' ', f);
+                else
+                        with_leading_space = true;
+                fputs(inet_ntop(AF_INET, &addresses[i], sbuf, sizeof(sbuf)), f);
+                count++;
+        }
+
+        return count;
 }
 
 int deserialize_in_addrs(struct in_addr **ret, const char *string) {
@@ -487,7 +477,7 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) {
                 size++;
         }
 
-        *ret = TAKE_PTR(addresses);
+        *ret = size > 0 ? TAKE_PTR(addresses) : NULL;
 
         return size;
 }
@@ -556,6 +546,7 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
         fprintf(f, "%s=", key);
 
         for (i = 0; i < size; i++) {
+                char sbuf[INET_ADDRSTRLEN];
                 struct in_addr dest, gw;
                 uint8_t length;
 
@@ -563,8 +554,8 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
                 assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0);
                 assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0);
 
-                fprintf(f, "%s/%" PRIu8, inet_ntoa(dest), length);
-                fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": "");
+                fprintf(f, "%s/%" PRIu8, inet_ntop(AF_INET, &dest, sbuf, sizeof(sbuf)), length);
+                fprintf(f, ",%s%s", inet_ntop(AF_INET, &gw, sbuf, sizeof(sbuf)), (i < (size - 1)) ? " ": "");
         }
 
         fputs("\n", f);
diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h
index 06d61184..9119d9a4 100644
--- a/src/systemd/src/libsystemd-network/network-internal.h
+++ b/src/systemd/src/libsystemd-network/network-internal.h
@@ -8,7 +8,9 @@
 
 #include "condition.h"
 #include "conf-parser.h"
+#include "def.h"
 #include "set.h"
+#include "strv.h"
 
 #define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
 #define LINK_BRIDGE_PORT_PRIORITY_MAX 63
@@ -25,7 +27,6 @@ bool net_match_config(Set *match_mac,
                       Condition *match_arch,
                       const struct ether_addr *dev_mac,
                       const char *dev_path,
-                      const char *dev_parent_driver,
                       const char *dev_driver,
                       const char *dev_type,
                       const char *dev_name);
@@ -36,14 +37,17 @@ CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
 CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
 CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
 CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
-CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
 CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
 
 int net_get_unique_predictable_data(sd_device *device, uint64_t *result);
 const char *net_get_name(sd_device *device);
 #endif /* NM_IGNORED */
 
-void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
+size_t serialize_in_addrs(FILE *f,
+                          const struct in_addr *addresses,
+                          size_t size,
+                          bool with_leading_space,
+                          bool (*predicate)(const struct in_addr *addr));
 int deserialize_in_addrs(struct in_addr **addresses, const char *string);
 void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
                          size_t size);
@@ -57,3 +61,5 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
 
 /* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
 int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
+
+#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 0c385a84..27f79638 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -3,9 +3,8 @@
   Copyright © 2013 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
 #include <stdio.h>
@@ -23,11 +22,13 @@
 #include "dhcp-lease-internal.h"
 #include "dhcp-protocol.h"
 #include "dns-domain.h"
+#include "event-util.h"
 #include "hostname-util.h"
+#include "io-util.h"
 #include "random-util.h"
 #include "string-util.h"
-#include "util.h"
 #include "strv.h"
+#include "util.h"
 
 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN)  /* Arbitrary limit */
 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
@@ -88,7 +89,7 @@ struct sd_dhcp_client {
         uint32_t mtu;
         uint32_t xid;
         usec_t start_time;
-        unsigned int attempt;
+        unsigned attempt;
         usec_t request_sent;
         sd_event_source *timeout_t1;
         sd_event_source *timeout_t2;
@@ -118,19 +119,19 @@ static const uint8_t default_req_opts[] = {
 */
 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
 static const uint8_t default_req_opts_anonymize[] = {
-       SD_DHCP_OPTION_SUBNET_MASK,                     /* 1 */
-       SD_DHCP_OPTION_ROUTER,                          /* 3 */
-       SD_DHCP_OPTION_DOMAIN_NAME_SERVER,              /* 6 */
-       SD_DHCP_OPTION_DOMAIN_NAME,                     /* 15 */
-       SD_DHCP_OPTION_ROUTER_DISCOVER,                 /* 31 */
-       SD_DHCP_OPTION_STATIC_ROUTE,                    /* 33 */
-       SD_DHCP_OPTION_VENDOR_SPECIFIC,                 /* 43 */
-       SD_DHCP_OPTION_NETBIOS_NAMESERVER,              /* 44 */
-       SD_DHCP_OPTION_NETBIOS_NODETYPE,                /* 46 */
-       SD_DHCP_OPTION_NETBIOS_SCOPE,                   /* 47 */
-       SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE,          /* 121 */
-       SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE,  /* 249 */
-       SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY,     /* 252 */
+        SD_DHCP_OPTION_SUBNET_MASK,                     /* 1 */
+        SD_DHCP_OPTION_ROUTER,                          /* 3 */
+        SD_DHCP_OPTION_DOMAIN_NAME_SERVER,              /* 6 */
+        SD_DHCP_OPTION_DOMAIN_NAME,                     /* 15 */
+        SD_DHCP_OPTION_ROUTER_DISCOVER,                 /* 31 */
+        SD_DHCP_OPTION_STATIC_ROUTE,                    /* 33 */
+        SD_DHCP_OPTION_VENDOR_SPECIFIC,                 /* 43 */
+        SD_DHCP_OPTION_NETBIOS_NAMESERVER,              /* 44 */
+        SD_DHCP_OPTION_NETBIOS_NODETYPE,                /* 46 */
+        SD_DHCP_OPTION_NETBIOS_SCOPE,                   /* 47 */
+        SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE,          /* 121 */
+        SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE,  /* 249 */
+        SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY,     /* 252 */
 };
 
 static int client_receive_message_raw(
@@ -342,8 +343,9 @@ int sd_dhcp_client_set_client_id(
  */
 static int dhcp_client_set_iaid_duid_internal(
                 sd_dhcp_client *client,
+                bool iaid_append,
+                bool iaid_set,
                 uint32_t iaid,
-                bool append_iaid,
                 uint16_t duid_type,
                 const void *duid,
                 size_t duid_len,
@@ -354,9 +356,9 @@ static int dhcp_client_set_iaid_duid_internal(
         size_t len;
 
         assert_return(client, -EINVAL);
-        assert_return(duid_len == 0 || duid != NULL, -EINVAL);
+        assert_return(duid_len == 0 || duid, -EINVAL);
 
-        if (duid != NULL) {
+        if (duid) {
                 r = dhcp_validate_duid_len(duid_type, duid_len, true);
                 if (r < 0)
                         return r;
@@ -365,26 +367,27 @@ static int dhcp_client_set_iaid_duid_internal(
         zero(client->client_id);
         client->client_id.type = 255;
 
-        if (append_iaid) {
-                /* If IAID is not configured, generate it. */
-                if (iaid == 0) {
+        if (iaid_append) {
+                if (iaid_set)
+                        client->client_id.ns.iaid = htobe32(iaid);
+                else {
                         r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
                                                      client->mac_addr_len,
+                                                     true,
                                                      &client->client_id.ns.iaid);
                         if (r < 0)
                                 return r;
-                } else
-                        client->client_id.ns.iaid = htobe32(iaid);
+                }
         }
 
-        if (duid != NULL) {
+        if (duid) {
                 client->client_id.ns.duid.type = htobe16(duid_type);
                 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
                 len = sizeof(client->client_id.ns.duid.type) + duid_len;
         } else
                 switch (duid_type) {
                 case DUID_TYPE_LLT:
-                        if (!client->mac_addr || client->mac_addr_len == 0)
+                        if (client->mac_addr_len == 0)
                                 return -EOPNOTSUPP;
 
                         r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
@@ -397,7 +400,7 @@ static int dhcp_client_set_iaid_duid_internal(
                                 return r;
                         break;
                 case DUID_TYPE_LL:
-                        if (!client->mac_addr || client->mac_addr_len == 0)
+                        if (client->mac_addr_len == 0)
                                 return -EOPNOTSUPP;
 
                         r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
@@ -414,10 +417,10 @@ static int dhcp_client_set_iaid_duid_internal(
                 }
 
         client->client_id_len = sizeof(client->client_id.type) + len +
-                                (append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
+                                (iaid_append ? sizeof(client->client_id.ns.iaid) : 0);
 
         if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
-                log_dhcp_client(client, "Configured %sDUID, restarting.", append_iaid ? "IAID+" : "");
+                log_dhcp_client(client, "Configured %sDUID, restarting.", iaid_append ? "IAID+" : "");
                 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
                 sd_dhcp_client_start(client);
         }
@@ -427,18 +430,20 @@ static int dhcp_client_set_iaid_duid_internal(
 
 int sd_dhcp_client_set_iaid_duid(
                 sd_dhcp_client *client,
+                bool iaid_set,
                 uint32_t iaid,
                 uint16_t duid_type,
                 const void *duid,
                 size_t duid_len) {
-        return dhcp_client_set_iaid_duid_internal(client, iaid, true, duid_type, duid, duid_len, 0);
+        return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, duid_type, duid, duid_len, 0);
 }
 
 int sd_dhcp_client_set_iaid_duid_llt(
                 sd_dhcp_client *client,
+                bool iaid_set,
                 uint32_t iaid,
                 usec_t llt_time) {
-        return dhcp_client_set_iaid_duid_internal(client, iaid, true, DUID_TYPE_LLT, NULL, 0, llt_time);
+        return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, DUID_TYPE_LLT, NULL, 0, llt_time);
 }
 
 int sd_dhcp_client_set_duid(
@@ -446,13 +451,13 @@ int sd_dhcp_client_set_duid(
                 uint16_t duid_type,
                 const void *duid,
                 size_t duid_len) {
-        return dhcp_client_set_iaid_duid_internal(client, 0, false, duid_type, duid, duid_len, 0);
+        return dhcp_client_set_iaid_duid_internal(client, false, false, 0, duid_type, duid, duid_len, 0);
 }
 
 int sd_dhcp_client_set_duid_llt(
                 sd_dhcp_client *client,
                 usec_t llt_time) {
-        return dhcp_client_set_iaid_duid_internal(client, 0, false, DUID_TYPE_LLT, NULL, 0, llt_time);
+        return dhcp_client_set_iaid_duid_internal(client, false, false, 0, DUID_TYPE_LLT, NULL, 0, llt_time);
 }
 #endif /* NM_IGNORED */
 
@@ -545,11 +550,10 @@ static int client_initialize(sd_dhcp_client *client) {
 
         client->fd = asynchronous_close(client->fd);
 
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
-        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
-        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
-        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
+        (void) event_source_disable(client->timeout_resend);
+        (void) event_source_disable(client->timeout_t1);
+        (void) event_source_disable(client->timeout_t2);
+        (void) event_source_disable(client->timeout_expire);
 
         client->attempt = 1;
 
@@ -650,7 +654,8 @@ static int client_message_init(
 
                 client->client_id.type = 255;
 
-                r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
+                r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
+                                             true, &client->client_id.ns.iaid);
                 if (r < 0)
                         return r;
 
@@ -698,7 +703,7 @@ static int client_message_init(
            let the server know how large the server may make its DHCP messages.
 
            Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
-           than the defined default size unless the Maximum Messge Size option
+           than the defined default size unless the Maximum Message Size option
            is explicitly set
 
            RFC3442 "Requirements to Avoid Sizing Constraints":
@@ -1063,22 +1068,11 @@ static int client_timeout_resend(
 
         next_timeout += (random_u32() & 0x1fffff);
 
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
-        r = sd_event_add_time(client->event,
-                              &client->timeout_resend,
-                              clock_boottime_or_monotonic(),
-                              next_timeout, 10 * USEC_PER_MSEC,
-                              client_timeout_resend, client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
+        r = event_reset_time(client->event, &client->timeout_resend,
+                             clock_boottime_or_monotonic(),
+                             next_timeout, 10 * USEC_PER_MSEC,
+                             client_timeout_resend, client,
+                             client->event_priority, "dhcp4-resend-timer", true);
         if (r < 0)
                 goto error;
 
@@ -1175,31 +1169,16 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
         assert(client);
         assert(client->event);
 
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
         if (client->start_delay) {
                 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
                 usec += client->start_delay;
         }
 
-        r = sd_event_add_time(client->event,
-                              &client->timeout_resend,
-                              clock_boottime_or_monotonic(),
-                              usec, 0,
-                              client_timeout_resend, client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
-        if (r < 0)
-                goto error;
-
-error:
+        r = event_reset_time(client->event, &client->timeout_resend,
+                             clock_boottime_or_monotonic(),
+                             usec, 0,
+                             client_timeout_resend, client,
+                             client->event_priority, "dhcp4-resend-timer", true);
         if (r < 0)
                 client_stop(client, r);
 
@@ -1457,13 +1436,14 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
         assert(client->lease);
         assert(client->lease->lifetime);
 
-        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
-        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
-        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
         /* don't set timers for infinite leases */
-        if (client->lease->lifetime == 0xffffffff)
+        if (client->lease->lifetime == 0xffffffff) {
+                (void) event_source_disable(client->timeout_t1);
+                (void) event_source_disable(client->timeout_t2);
+                (void) event_source_disable(client->timeout_expire);
+
                 return 0;
+        }
 
         r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
         if (r < 0)
@@ -1515,19 +1495,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
         }
 
         /* arm lifetime timeout */
-        r = sd_event_add_time(client->event, &client->timeout_expire,
-                              clock_boottime_or_monotonic(),
-                              lifetime_timeout, 10 * USEC_PER_MSEC,
-                              client_timeout_expire, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_expire,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
+        r = event_reset_time(client->event, &client->timeout_expire,
+                             clock_boottime_or_monotonic(),
+                             lifetime_timeout, 10 * USEC_PER_MSEC,
+                             client_timeout_expire, client,
+                             client->event_priority, "dhcp4-lifetime", true);
         if (r < 0)
                 return r;
 
@@ -1539,21 +1511,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
                 return 0;
 
         /* arm T2 timeout */
-        r = sd_event_add_time(client->event,
-                              &client->timeout_t2,
-                              clock_boottime_or_monotonic(),
-                              t2_timeout,
-                              10 * USEC_PER_MSEC,
-                              client_timeout_t2, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_t2,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
+        r = event_reset_time(client->event, &client->timeout_t2,
+                             clock_boottime_or_monotonic(),
+                             t2_timeout, 10 * USEC_PER_MSEC,
+                             client_timeout_t2, client,
+                             client->event_priority, "dhcp4-t2-timeout", true);
         if (r < 0)
                 return r;
 
@@ -1565,20 +1527,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
                 return 0;
 
         /* arm T1 timeout */
-        r = sd_event_add_time(client->event,
-                              &client->timeout_t1,
-                              clock_boottime_or_monotonic(),
-                              t1_timeout, 10 * USEC_PER_MSEC,
-                              client_timeout_t1, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_t1,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
+        r = event_reset_time(client->event, &client->timeout_t1,
+                             clock_boottime_or_monotonic(),
+                             t1_timeout, 10 * USEC_PER_MSEC,
+                             client_timeout_t1, client,
+                             client->event_priority, "dhcp4-t1-timer", true);
         if (r < 0)
                 return r;
 
@@ -1603,26 +1556,14 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
                 r = client_handle_offer(client, message, len);
                 if (r >= 0) {
 
-                        client->timeout_resend =
-                                sd_event_source_unref(client->timeout_resend);
-
                         client->state = DHCP_STATE_REQUESTING;
                         client->attempt = 1;
 
-                        r = sd_event_add_time(client->event,
-                                              &client->timeout_resend,
-                                              clock_boottime_or_monotonic(),
-                                              0, 0,
-                                              client_timeout_resend, client);
-                        if (r < 0)
-                                goto error;
-
-                        r = sd_event_source_set_priority(client->timeout_resend,
-                                                         client->event_priority);
-                        if (r < 0)
-                                goto error;
-
-                        r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
+                        r = event_reset_time(client->event, &client->timeout_resend,
+                                             clock_boottime_or_monotonic(),
+                                             0, 0,
+                                             client_timeout_resend, client,
+                                             client->event_priority, "dhcp4-resend-timer", true);
                         if (r < 0)
                                 goto error;
                 } else if (r == -ENOMSG)
@@ -1639,8 +1580,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
                 r = client_handle_ack(client, message, len);
                 if (r >= 0) {
                         client->start_delay = 0;
-                        client->timeout_resend =
-                                sd_event_source_unref(client->timeout_resend);
+                        (void) event_source_disable(client->timeout_resend);
                         client->receive_message =
                                 sd_event_source_unref(client->receive_message);
                         client->fd = asynchronous_close(client->fd);
@@ -1680,9 +1620,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
 
                 } else if (r == -EADDRNOTAVAIL) {
                         /* got a NAK, let's restart the client */
-                        client->timeout_resend =
-                                sd_event_source_unref(client->timeout_resend);
-
                         client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
 
                         r = client_initialize(client);
@@ -1743,8 +1680,7 @@ static int client_receive_message_udp(
 
         sd_dhcp_client *client = userdata;
         _cleanup_free_ DHCPMessage *message = NULL;
-        const struct ether_addr zero_mac = {};
-        const struct ether_addr *expected_chaddr = NULL;
+        const uint8_t *expected_chaddr = NULL;
         uint8_t expected_hlen = 0;
         ssize_t len, buflen;
 
@@ -1752,6 +1688,12 @@ static int client_receive_message_udp(
         assert(client);
 
         buflen = next_datagram_size_fd(fd);
+        if (buflen == -ENETDOWN) {
+                /* the link is down. Don't return an error or the I/O event
+                   source will be disconnected and we won't be able to receive
+                   packets again when the link comes back. */
+                return 0;
+        }
         if (buflen < 0)
                 return buflen;
 
@@ -1761,7 +1703,8 @@ static int client_receive_message_udp(
 
         len = recv(fd, message, buflen, 0);
         if (len < 0) {
-                if (IN_SET(errno, EAGAIN, EINTR))
+                /* see comment above for why we shouldn't error out on ENETDOWN. */
+                if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
                         return 0;
 
                 return log_dhcp_client_errno(client, errno,
@@ -1789,11 +1732,7 @@ static int client_receive_message_udp(
 
         if (client->arp_type == ARPHRD_ETHER) {
                 expected_hlen = ETH_ALEN;
-                expected_chaddr = (const struct ether_addr *) &client->mac_addr;
-        } else {
-               /* Non-Ethernet links expect zero chaddr */
-               expected_hlen = 0;
-               expected_chaddr = &zero_mac;
+                expected_chaddr = &client->mac_addr[0];
         }
 
         if (message->hlen != expected_hlen) {
@@ -1801,7 +1740,7 @@ static int client_receive_message_udp(
                 return 0;
         }
 
-        if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
+        if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
                 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
                 return 0;
         }
@@ -1843,6 +1782,8 @@ static int client_receive_message_raw(
         assert(client);
 
         buflen = next_datagram_size_fd(fd);
+        if (buflen == -ENETDOWN)
+                return 0;
         if (buflen < 0)
                 return buflen;
 
@@ -1850,12 +1791,11 @@ static int client_receive_message_raw(
         if (!packet)
                 return -ENOMEM;
 
-        iov.iov_base = packet;
-        iov.iov_len = buflen;
+        iov = IOVEC_MAKE(packet, buflen);
 
         len = recvmsg(fd, &msg, 0);
         if (len < 0) {
-                if (IN_SET(errno, EAGAIN, EINTR))
+                if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
                         return 0;
 
                 return log_dhcp_client_errno(client, errno,
@@ -1863,7 +1803,7 @@ static int client_receive_message_raw(
         } else if ((size_t)len < sizeof(DHCPPacket))
                 return 0;
 
-        CMSG_FOREACH(cmsg, &msg) {
+        CMSG_FOREACH(cmsg, &msg)
                 if (cmsg->cmsg_level == SOL_PACKET &&
                     cmsg->cmsg_type == PACKET_AUXDATA &&
                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
@@ -1872,7 +1812,6 @@ static int client_receive_message_raw(
                         checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
                         break;
                 }
-        }
 
         r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
         if (r < 0)
@@ -1953,33 +1892,17 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
         return client->event;
 }
 
-sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
-
-        if (!client)
-                return NULL;
-
-        assert(client->n_ref >= 1);
-        client->n_ref++;
-
-        return client;
-}
-
-sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
-
-        if (!client)
-                return NULL;
-
-        assert(client->n_ref >= 1);
-        client->n_ref--;
-
-        if (client->n_ref > 0)
-                return NULL;
+static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
+        assert(client);
 
         log_dhcp_client(client, "FREE");
 
-        client_initialize(client);
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
 
-        client->receive_message = sd_event_source_unref(client->receive_message);
+        client_initialize(client);
 
         sd_dhcp_client_detach_event(client);
 
@@ -1992,24 +1915,27 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
         return mfree(client);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
+
 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
         _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
 
         assert_return(ret, -EINVAL);
 
-        client = new0(sd_dhcp_client, 1);
+        client = new(sd_dhcp_client, 1);
         if (!client)
                 return -ENOMEM;
 
-        client->n_ref = 1;
-        client->state = DHCP_STATE_INIT;
-        client->ifindex = -1;
-        client->fd = -1;
-        client->attempt = 1;
-        client->mtu = DHCP_DEFAULT_MIN_SIZE;
-        client->port = DHCP_PORT_CLIENT;
-
-        client->anonymize = !!anonymize;
+        *client = (sd_dhcp_client) {
+                .n_ref = 1,
+                .state = DHCP_STATE_INIT,
+                .ifindex = -1,
+                .fd = -1,
+                .attempt = 1,
+                .mtu = DHCP_DEFAULT_MIN_SIZE,
+                .port = DHCP_PORT_CLIENT,
+                .anonymize = !!anonymize,
+        };
         /* NOTE: this could be moved to a function. */
         if (anonymize) {
                 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index cac07d3e..39d2a6d0 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -3,10 +3,9 @@
   Copyright © 2013 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <arpa/inet.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdio_ext.h>
 #include <stdlib.h>
@@ -18,6 +17,7 @@
 #include "dhcp-lease-internal.h"
 #include "dhcp-protocol.h"
 #include "dns-domain.h"
+#include "env-file.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "hexdecoct.h"
@@ -28,6 +28,7 @@
 #include "stdio-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "tmpfile-util.h"
 #include "unaligned.h"
 
 int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
@@ -151,15 +152,15 @@ int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
         return 0;
 }
 
-int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
+int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr) {
         assert_return(lease, -EINVAL);
         assert_return(addr, -EINVAL);
 
-        if (lease->router == 0)
+        if (lease->router_size <= 0)
                 return -ENODATA;
 
-        addr->s_addr = lease->router;
-        return 0;
+        *addr = lease->router;
+        return (int) lease->router_size;
 }
 
 int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
@@ -248,27 +249,8 @@ int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, s
         return 0;
 }
 
-sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
-
-        if (!lease)
-                return NULL;
-
-        assert(lease->n_ref >= 1);
-        lease->n_ref++;
-
-        return lease;
-}
-
-sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
-
-        if (!lease)
-                return NULL;
-
-        assert(lease->n_ref >= 1);
-        lease->n_ref--;
-
-        if (lease->n_ref > 0)
-                return NULL;
+static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
+        assert(lease);
 
         while (lease->private_options) {
                 struct sd_dhcp_raw_option *option = lease->private_options;
@@ -280,6 +262,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
         }
 
         free(lease->root_path);
+        free(lease->router);
         free(lease->timezone);
         free(lease->hostname);
         free(lease->domainname);
@@ -292,6 +275,8 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
         return mfree(lease);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_lease, sd_dhcp_lease, dhcp_lease_free);
+
 static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
         assert(option);
         assert(ret);
@@ -351,8 +336,7 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
                 if (!string)
                         return -ENOMEM;
 
-                free(*ret);
-                *ret = string;
+                free_and_replace(*ret, string);
         }
 
         return 0;
@@ -373,7 +357,7 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
                 return 0;
         }
 
-        r = dns_name_normalize(name, &normalized);
+        r = dns_name_normalize(name, 0, &normalized);
         if (r < 0)
                 return r;
 
@@ -388,23 +372,6 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
         return 0;
 }
 
-static void filter_bogus_addresses(struct in_addr *addresses, size_t *n) {
-        size_t i, j;
-
-        /* Silently filter DNS/NTP servers supplied to us that do not make outside of the local scope. */
-
-        for (i = 0, j = 0; i < *n; i ++) {
-
-                if (in4_addr_is_null(addresses+i) ||
-                    in4_addr_is_localhost(addresses+i))
-                        continue;
-
-                addresses[j++] = addresses[i];
-        }
-
-        *n = j;
-}
-
 static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
         assert(option);
         assert(ret);
@@ -426,8 +393,6 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
                 if (!addresses)
                         return -ENOMEM;
 
-                filter_bogus_addresses(addresses, &n_addresses);
-
                 free(*ret);
                 *ret = addresses;
                 *n_ret = n_addresses;
@@ -572,11 +537,9 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
                 break;
 
         case SD_DHCP_OPTION_ROUTER:
-                if (len >= 4) {
-                        r = lease_parse_be32(option, 4, &lease->router);
-                        if (r < 0)
-                                log_debug_errno(r, "Failed to parse router address, ignoring: %m");
-                }
+                r = lease_parse_in_addrs(option, len, &lease->router, &lease->router_size);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to parse router addresses, ignoring: %m");
                 break;
 
         case SD_DHCP_OPTION_DOMAIN_NAME_SERVER:
@@ -838,7 +801,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) {
         if (!lease)
                 return -ENOMEM;
 
-        lease->router = INADDR_ANY;
         lease->n_ref = 1;
 
         *ret = lease;
@@ -853,6 +815,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
         const struct in_addr *addresses;
         const void *client_id, *data;
         size_t client_id_len, data_len;
+        char sbuf[INET_ADDRSTRLEN];
         const char *string;
         uint16_t mtu;
         _cleanup_free_ sd_dhcp_route **routes = NULL;
@@ -875,27 +838,30 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
 
         r = sd_dhcp_lease_get_address(lease, &address);
         if (r >= 0)
-                fprintf(f, "ADDRESS=%s\n", inet_ntoa(address));
+                fprintf(f, "ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
 
         r = sd_dhcp_lease_get_netmask(lease, &address);
         if (r >= 0)
-                fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
+                fprintf(f, "NETMASK=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
 
-        r = sd_dhcp_lease_get_router(lease, &address);
-        if (r >= 0)
-                fprintf(f, "ROUTER=%s\n", inet_ntoa(address));
+        r = sd_dhcp_lease_get_router(lease, &addresses);
+        if (r > 0) {
+                fputs("ROUTER=", f);
+                serialize_in_addrs(f, addresses, r, false, NULL);
+                fputc('\n', f);
+        }
 
         r = sd_dhcp_lease_get_server_identifier(lease, &address);
         if (r >= 0)
-                fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntoa(address));
+                fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
 
         r = sd_dhcp_lease_get_next_server(lease, &address);
         if (r >= 0)
-                fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
+                fprintf(f, "NEXT_SERVER=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
 
         r = sd_dhcp_lease_get_broadcast(lease, &address);
         if (r >= 0)
-                fprintf(f, "BROADCAST=%s\n", inet_ntoa(address));
+                fprintf(f, "BROADCAST=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
 
         r = sd_dhcp_lease_get_mtu(lease, &mtu);
         if (r >= 0)
@@ -916,15 +882,15 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
         r = sd_dhcp_lease_get_dns(lease, &addresses);
         if (r > 0) {
                 fputs("DNS=", f);
-                serialize_in_addrs(f, addresses, r);
-                fputs("\n", f);
+                serialize_in_addrs(f, addresses, r, false, NULL);
+                fputc('\n', f);
         }
 
         r = sd_dhcp_lease_get_ntp(lease, &addresses);
         if (r > 0) {
                 fputs("NTP=", f);
-                serialize_in_addrs(f, addresses, r);
-                fputs("\n", f);
+                serialize_in_addrs(f, addresses, r, false, NULL);
+                fputc('\n', f);
         }
 
         r = sd_dhcp_lease_get_domainname(lease, &string);
@@ -935,7 +901,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
         if (r > 0) {
                 fputs("DOMAIN_SEARCH_LIST=", f);
                 fputstrv(f, search_domains, NULL, NULL);
-                fputs("\n", f);
+                fputc('\n', f);
         }
 
         r = sd_dhcp_lease_get_hostname(lease, &string);
@@ -1036,7 +1002,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
         if (r < 0)
                 return r;
 
-        r = parse_env_file(NULL, lease_file, NEWLINE,
+        r = parse_env_file(NULL, lease_file,
                            "ADDRESS", &address,
                            "ROUTER", &router,
                            "NETMASK", &netmask,
@@ -1087,8 +1053,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
                            "OPTION_251", &options[27],
                            "OPTION_252", &options[28],
                            "OPTION_253", &options[29],
-                           "OPTION_254", &options[30],
-                           NULL);
+                           "OPTION_254", &options[30]);
         if (r < 0)
                 return r;
 
@@ -1099,9 +1064,11 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
         }
 
         if (router) {
-                r = inet_pton(AF_INET, router, &lease->router);
-                if (r <= 0)
-                        log_debug("Failed to parse router %s, ignoring.", router);
+                r = deserialize_in_addrs(&lease->router, router);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to deserialize router addresses %s, ignoring: %m", router);
+                else
+                        lease->router_size = r;
         }
 
         if (netmask) {
@@ -1320,3 +1287,9 @@ int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
         *gateway = route->gw_addr;
         return 0;
 }
+
+int sd_dhcp_route_get_option(sd_dhcp_route *route) {
+        assert_return(route, -EINVAL);
+
+        return route->option;
+}
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index f0cd2f97..b72cd82d 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -3,9 +3,8 @@
   Copyright © 2014-2015 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <linux/if_infiniband.h>
@@ -18,6 +17,7 @@
 #include "dhcp6-lease-internal.h"
 #include "dhcp6-protocol.h"
 #include "dns-domain.h"
+#include "event-util.h"
 #include "fd-util.h"
 #include "hostname-util.h"
 #include "in-addr-util.h"
@@ -29,6 +29,13 @@
 
 #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
 
+/* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
+enum {
+        DHCP6_REQUEST_IA_NA                     = 1,
+        DHCP6_REQUEST_IA_TA                     = 2, /* currently not used */
+        DHCP6_REQUEST_IA_PD                     = 4,
+};
+
 struct sd_dhcp6_client {
         unsigned n_ref;
 
@@ -42,12 +49,15 @@ struct sd_dhcp6_client {
         uint16_t arp_type;
         DHCP6IA ia_na;
         DHCP6IA ia_pd;
-        bool prefix_delegation;
+        sd_event_source *timeout_t1;
+        sd_event_source *timeout_t2;
+        unsigned request;
         be32_t transaction_id;
         usec_t transaction_start;
         struct sd_dhcp6_lease *lease;
         int fd;
         bool information_request;
+        bool iaid_set;
         be16_t *req_opts;
         size_t req_opts_allocated;
         size_t req_opts_len;
@@ -212,10 +222,10 @@ static int dhcp6_client_set_duid_internal(
 #if 0 /* NM_IGNORED */
                 switch (duid_type) {
                 case DUID_TYPE_LLT:
-                        if (!client->mac_addr || client->mac_addr_len == 0)
+                        if (client->mac_addr_len == 0)
                                 return -EOPNOTSUPP;
 
-                        r = dhcp_identifier_set_duid_llt(&client->duid, 0, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
+                        r = dhcp_identifier_set_duid_llt(&client->duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
                         if (r < 0)
                                 return r;
                         break;
@@ -225,7 +235,7 @@ static int dhcp6_client_set_duid_internal(
                                 return r;
                         break;
                 case DUID_TYPE_LL:
-                        if (!client->mac_addr || client->mac_addr_len == 0)
+                        if (client->mac_addr_len == 0)
                                 return -EOPNOTSUPP;
 
                         r = dhcp_identifier_set_duid_ll(&client->duid, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
@@ -255,7 +265,6 @@ int sd_dhcp6_client_set_duid(
         return dhcp6_client_set_duid_internal(client, duid_type, duid, duid_len, 0);
 }
 
-#if 0 /* NM_IGNORED */
 int sd_dhcp6_client_set_duid_llt(
                 sd_dhcp6_client *client,
                 usec_t llt_time) {
@@ -268,10 +277,10 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
 
         client->ia_na.ia_na.id = htobe32(iaid);
         client->ia_pd.ia_pd.id = htobe32(iaid);
+        client->iaid_set = true;
 
         return 0;
 }
-#endif /* NM_IGNORED */
 
 int sd_dhcp6_client_set_fqdn(
                 sd_dhcp6_client *client,
@@ -337,10 +346,44 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
         return 0;
 }
 
-int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, bool delegation) {
+int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
+        assert_return(client, -EINVAL);
+        assert_return(delegation, -EINVAL);
+
+        *delegation = FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD);
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, int delegation) {
+        assert_return(client, -EINVAL);
+
+        SET_FLAG(client->request, DHCP6_REQUEST_IA_PD, delegation);
+
+        return 0;
+}
+
+int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, int *request) {
+        assert_return(client, -EINVAL);
+        assert_return(request, -EINVAL);
+
+        *request = FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA);
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) {
         assert_return(client, -EINVAL);
 
-        client->prefix_delegation = delegation;
+        SET_FLAG(client->request, DHCP6_REQUEST_IA_NA, request);
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id) {
+        assert_return(client, -EINVAL);
+
+        client->transaction_id = transaction_id;
 
         return 0;
 }
@@ -364,21 +407,10 @@ static void client_notify(sd_dhcp6_client *client, int event) {
                 client->callback(client, event, client->userdata);
 }
 
-static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) {
-        assert(client);
-
-        if (client->lease) {
-                dhcp6_lease_clear_timers(&client->lease->ia);
-                sd_dhcp6_lease_unref(client->lease);
-        }
-
-        client->lease = lease;
-}
-
 static int client_reset(sd_dhcp6_client *client) {
         assert(client);
 
-        client_set_lease(client, NULL);
+        client->lease = sd_dhcp6_lease_unref(client->lease);
 
         client->receive_message =
                 sd_event_source_unref(client->receive_message);
@@ -386,16 +418,13 @@ static int client_reset(sd_dhcp6_client *client) {
         client->transaction_id = 0;
         client->transaction_start = 0;
 
-        client->ia_na.timeout_t1 =
-                sd_event_source_unref(client->ia_na.timeout_t1);
-        client->ia_na.timeout_t2 =
-                sd_event_source_unref(client->ia_na.timeout_t2);
-
         client->retransmit_time = 0;
         client->retransmit_count = 0;
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-        client->timeout_resend_expire =
-                sd_event_source_unref(client->timeout_resend_expire);
+
+        (void) event_source_disable(client->timeout_resend);
+        (void) event_source_disable(client->timeout_resend_expire);
+        (void) event_source_disable(client->timeout_t1);
+        (void) event_source_disable(client->timeout_t2);
 
         client->state = DHCP6_STATE_STOPPED;
 
@@ -448,9 +477,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
-                r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
-                if (r < 0)
-                        return r;
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) {
+                        r = dhcp6_option_append_ia(&opt, &optlen,
+                                                   &client->ia_na);
+                        if (r < 0)
+                                return r;
+                }
 
                 if (client->fqdn) {
                         r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
@@ -458,7 +490,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (client->prefix_delegation) {
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
                         r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd);
                         if (r < 0)
                                 return r;
@@ -483,9 +515,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
-                r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
-                if (r < 0)
-                        return r;
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) {
+                        r = dhcp6_option_append_ia(&opt, &optlen,
+                                                   &client->lease->ia);
+                        if (r < 0)
+                                return r;
+                }
 
                 if (client->fqdn) {
                         r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
@@ -493,7 +528,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (client->prefix_delegation) {
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
                         r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd);
                         if (r < 0)
                                 return r;
@@ -507,9 +542,11 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
         case DHCP6_STATE_REBIND:
                 message->type = DHCP6_REBIND;
 
-                r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
-                if (r < 0)
-                        return r;
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) {
+                        r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
+                        if (r < 0)
+                                return r;
+                }
 
                 if (client->fqdn) {
                         r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
@@ -517,7 +554,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (client->prefix_delegation) {
+                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
                         r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd);
                         if (r < 0)
                                 return r;
@@ -574,8 +611,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
         assert(client);
         assert(client->lease);
 
-        client->lease->ia.timeout_t2 =
-                sd_event_source_unref(client->lease->ia.timeout_t2);
+        (void) event_source_disable(client->timeout_t2);
 
         log_dhcp6_client(client, "Timeout T2");
 
@@ -591,8 +627,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
         assert(client);
         assert(client->lease);
 
-        client->lease->ia.timeout_t1 =
-                sd_event_source_unref(client->lease->ia.timeout_t1);
+        (void) event_source_disable(client->timeout_t1);
 
         log_dhcp6_client(client, "Timeout T1");
 
@@ -640,7 +675,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
         assert(client);
         assert(client->event);
 
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        (void) event_source_disable(client->timeout_resend);
 
         switch (client->state) {
         case DHCP6_STATE_INFORMATION_REQUEST:
@@ -682,7 +717,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
                 init_retransmit_time = DHCP6_REB_TIMEOUT;
                 max_retransmit_time = DHCP6_REB_MAX_RT;
 
-                if (!client->timeout_resend_expire) {
+                if (event_source_is_enabled(client->timeout_resend_expire) <= 0) {
                         r = dhcp6_lease_ia_rebind_expire(&client->lease->ia,
                                                          &expire);
                         if (r < 0) {
@@ -731,43 +766,24 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
         log_dhcp6_client(client, "Next retransmission in %s",
                          format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->retransmit_time, USEC_PER_SEC));
 
-        r = sd_event_add_time(client->event, &client->timeout_resend,
-                              clock_boottime_or_monotonic(),
-                              time_now + client->retransmit_time,
-                              10 * USEC_PER_MSEC, client_timeout_resend,
-                              client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer");
+        r = event_reset_time(client->event, &client->timeout_resend,
+                             clock_boottime_or_monotonic(),
+                             time_now + client->retransmit_time, 10 * USEC_PER_MSEC,
+                             client_timeout_resend, client,
+                             client->event_priority, "dhcp6-resend-timer", true);
         if (r < 0)
                 goto error;
 
-        if (max_retransmit_duration && !client->timeout_resend_expire) {
+        if (max_retransmit_duration && event_source_is_enabled(client->timeout_resend_expire) <= 0) {
 
                 log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs",
                                  max_retransmit_duration / USEC_PER_SEC);
 
-                r = sd_event_add_time(client->event,
-                                      &client->timeout_resend_expire,
-                                      clock_boottime_or_monotonic(),
-                                      time_now + max_retransmit_duration,
-                                      USEC_PER_SEC,
-                                      client_timeout_resend_expire, client);
-                if (r < 0)
-                        goto error;
-
-                r = sd_event_source_set_priority(client->timeout_resend_expire,
-                                                 client->event_priority);
-                if (r < 0)
-                        goto error;
-
-                r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer");
+                r = event_reset_time(client->event, &client->timeout_resend_expire,
+                                     clock_boottime_or_monotonic(),
+                                     time_now + max_retransmit_duration, USEC_PER_SEC,
+                                     client_timeout_resend_expire, client,
+                                     client->event_priority, "dhcp6-resend-expire-timer", true);
                 if (r < 0)
                         goto error;
         }
@@ -781,19 +797,20 @@ error:
 
 static int client_ensure_iaid(sd_dhcp6_client *client) {
         int r;
-        be32_t iaid;
+        uint32_t iaid;
 
         assert(client);
 
-        if (client->ia_na.ia_na.id)
+        if (client->iaid_set)
                 return 0;
 
-        r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &iaid);
+        r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &iaid);
         if (r < 0)
                 return r;
 
         client->ia_na.ia_na.id = iaid;
         client->ia_pd.ia_pd.id = iaid;
+        client->iaid_set = true;
 
         return 0;
 }
@@ -803,10 +820,11 @@ static int client_parse_message(
                 DHCP6Message *message,
                 size_t len,
                 sd_dhcp6_lease *lease) {
+
+        uint32_t lt_t1 = ~0, lt_t2 = ~0;
+        bool clientid = false;
         size_t pos = 0;
         int r;
-        bool clientid = false;
-        uint32_t lt_t1 = ~0, lt_t2 = ~0;
 
         assert(client);
         assert(message);
@@ -816,20 +834,22 @@ static int client_parse_message(
         len -= sizeof(DHCP6Message);
 
         while (pos < len) {
-                DHCP6Option *option = (DHCP6Option *)&message->options[pos];
+                DHCP6Option *option = (DHCP6Option *) &message->options[pos];
                 uint16_t optcode, optlen;
-                int status;
-                uint8_t *optval;
                 be32_t iaid_lease;
+                uint8_t *optval;
+                int status;
 
-                if (len < pos + offsetof(DHCP6Option, data) ||
-                    len < pos + offsetof(DHCP6Option, data) + be16toh(option->len))
+                if (len < pos + offsetof(DHCP6Option, data))
                         return -ENOBUFS;
 
                 optcode = be16toh(option->code);
                 optlen = be16toh(option->len);
                 optval = option->data;
 
+                if (len < pos + offsetof(DHCP6Option, data) + optlen)
+                        return -ENOBUFS;
+
                 switch (optcode) {
                 case SD_DHCP6_OPTION_CLIENTID:
                         if (clientid) {
@@ -927,7 +947,7 @@ static int client_parse_message(
                         if (r < 0 && r != -ENOMSG)
                                 return r;
 
-                        r = dhcp6_lease_get_iaid(lease, &iaid_lease);
+                        r = dhcp6_lease_get_pd_iaid(lease, &iaid_lease);
                         if (r < 0)
                                 return r;
 
@@ -980,7 +1000,7 @@ static int client_parse_message(
                         break;
                 }
 
-                pos += sizeof(*option) + optlen;
+                pos += offsetof(DHCP6Option, data) + optlen;
         }
 
         if (!clientid) {
@@ -1040,8 +1060,8 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si
                         return 0;
         }
 
-        client_set_lease(client, lease);
-        lease = NULL;
+        sd_dhcp6_lease_unref(client->lease);
+        client->lease = TAKE_PTR(lease);
 
         return DHCP6_STATE_BOUND;
 }
@@ -1069,8 +1089,8 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
         r = dhcp6_lease_get_preference(client->lease, &pref_lease);
 
         if (r < 0 || pref_advertise > pref_lease) {
-                client_set_lease(client, lease);
-                lease = NULL;
+                sd_dhcp6_lease_unref(client->lease);
+                client->lease = TAKE_PTR(lease);
                 r = 0;
         }
 
@@ -1097,6 +1117,12 @@ static int client_receive_message(
         assert(client->event);
 
         buflen = next_datagram_size_fd(fd);
+        if (buflen == -ENETDOWN) {
+                /* the link is down. Don't return an error or the I/O event
+                   source will be disconnected and we won't be able to receive
+                   packets again when the link comes back. */
+                return 0;
+        }
         if (buflen < 0)
                 return buflen;
 
@@ -1106,7 +1132,8 @@ static int client_receive_message(
 
         len = recv(fd, message, buflen, 0);
         if (len < 0) {
-                if (IN_SET(errno, EAGAIN, EINTR))
+                /* see comment above for why we shouldn't error out on ENETDOWN. */
+                if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
                         return 0;
 
                 return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");
@@ -1201,19 +1228,41 @@ static int client_receive_message(
         return 0;
 }
 
+static int client_get_lifetime(sd_dhcp6_client *client, uint32_t *lifetime_t1,
+                               uint32_t *lifetime_t2) {
+        assert_return(client, -EINVAL);
+        assert_return(client->lease, -EINVAL);
+
+        if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) {
+                *lifetime_t1 = be32toh(client->lease->ia.ia_na.lifetime_t1);
+                *lifetime_t2 = be32toh(client->lease->ia.ia_na.lifetime_t2);
+
+                return 0;
+        }
+
+        if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
+                *lifetime_t1 = be32toh(client->lease->pd.ia_pd.lifetime_t1);
+                *lifetime_t2 = be32toh(client->lease->pd.ia_pd.lifetime_t2);
+
+                return 0;
+        }
+
+        return -ENOMSG;
+}
+
 static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
         int r;
         usec_t timeout, time_now;
         char time_string[FORMAT_TIMESPAN_MAX];
+        uint32_t lifetime_t1, lifetime_t2;
 
         assert_return(client, -EINVAL);
         assert_return(client->event, -EINVAL);
         assert_return(client->ifindex > 0, -EINVAL);
         assert_return(client->state != state, -EINVAL);
 
-        client->timeout_resend_expire =
-                sd_event_source_unref(client->timeout_resend_expire);
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        (void) event_source_disable(client->timeout_resend_expire);
+        (void) event_source_disable(client->timeout_resend);
         client->retransmit_time = 0;
         client->retransmit_count = 0;
 
@@ -1264,59 +1313,40 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
 
         case DHCP6_STATE_BOUND:
 
-                if (client->lease->ia.ia_na.lifetime_t1 == 0xffffffff ||
-                    client->lease->ia.ia_na.lifetime_t2 == 0xffffffff) {
+                r = client_get_lifetime(client, &lifetime_t1, &lifetime_t2);
+                if (r < 0)
+                        goto error;
 
+                if (lifetime_t1 == 0xffffffff || lifetime_t2 == 0xffffffff) {
                         log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x",
-                                         be32toh(client->lease->ia.ia_na.lifetime_t1),
-                                         be32toh(client->lease->ia.ia_na.lifetime_t2));
+                                         lifetime_t1, lifetime_t2);
 
                         return 0;
                 }
 
-                timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t1) * USEC_PER_SEC);
+                timeout = client_timeout_compute_random(lifetime_t1 * USEC_PER_SEC);
 
                 log_dhcp6_client(client, "T1 expires in %s",
                                  format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
 
-                client->lease->ia.timeout_t1 = sd_event_source_unref(client->lease->ia.timeout_t1);
-                r = sd_event_add_time(client->event,
-                                      &client->lease->ia.timeout_t1,
-                                      clock_boottime_or_monotonic(), time_now + timeout,
-                                      10 * USEC_PER_SEC, client_timeout_t1,
-                                      client);
+                r = event_reset_time(client->event, &client->timeout_t1,
+                                     clock_boottime_or_monotonic(),
+                                     time_now + timeout, 10 * USEC_PER_SEC,
+                                     client_timeout_t1, client,
+                                     client->event_priority, "dhcp6-t1-timeout", true);
                 if (r < 0)
                         goto error;
 
-                r = sd_event_source_set_priority(client->lease->ia.timeout_t1,
-                                                 client->event_priority);
-                if (r < 0)
-                        goto error;
-
-                r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout");
-                if (r < 0)
-                        goto error;
-
-                timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t2) * USEC_PER_SEC);
+                timeout = client_timeout_compute_random(lifetime_t2 * USEC_PER_SEC);
 
                 log_dhcp6_client(client, "T2 expires in %s",
                                  format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
 
-                client->lease->ia.timeout_t2 = sd_event_source_unref(client->lease->ia.timeout_t2);
-                r = sd_event_add_time(client->event,
-                                      &client->lease->ia.timeout_t2,
-                                      clock_boottime_or_monotonic(), time_now + timeout,
-                                      10 * USEC_PER_SEC, client_timeout_t2,
-                                      client);
-                if (r < 0)
-                        goto error;
-
-                r = sd_event_source_set_priority(client->lease->ia.timeout_t2,
-                                                 client->event_priority);
-                if (r < 0)
-                        goto error;
-
-                r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout");
+                r = event_reset_time(client->event, &client->timeout_t2,
+                                     clock_boottime_or_monotonic(),
+                                     time_now + timeout, 10 * USEC_PER_SEC,
+                                     client_timeout_t2, client,
+                                     client->event_priority, "dhcp6-t2-timeout", true);
                 if (r < 0)
                         goto error;
 
@@ -1328,18 +1358,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
         client->transaction_id = random_u32() & htobe32(0x00ffffff);
         client->transaction_start = time_now;
 
-        r = sd_event_add_time(client->event, &client->timeout_resend,
-                              clock_boottime_or_monotonic(), 0, 0, client_timeout_resend,
-                              client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout");
+        r = event_reset_time(client->event, &client->timeout_resend,
+                             clock_boottime_or_monotonic(),
+                             0, 0,
+                             client_timeout_resend, client,
+                             client->event_priority, "dhcp6-resend-timeout", true);
         if (r < 0)
                 goto error;
 
@@ -1378,6 +1401,9 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
         if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
                 return -EBUSY;
 
+        if (!client->information_request && !client->request)
+                return -EINVAL;
+
         r = client_reset(client);
         if (r < 0)
                 return r;
@@ -1446,27 +1472,13 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
         return client->event;
 }
 
-sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
-
-        if (!client)
-                return NULL;
-
-        assert(client->n_ref >= 1);
-        client->n_ref++;
-
-        return client;
-}
-
-sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
-
-        if (!client)
-                return NULL;
-
-        assert(client->n_ref >= 1);
-        client->n_ref--;
+static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
+        assert(client);
 
-        if (client->n_ref > 0)
-                return NULL;
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        client->timeout_resend_expire = sd_event_source_unref(client->timeout_resend_expire);
+        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
 
         client_reset(client);
 
@@ -1479,29 +1491,36 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
         return mfree(client);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_client, sd_dhcp6_client, dhcp6_client_free);
+
 int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
         _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
+        _cleanup_free_ be16_t *req_opts = NULL;
         size_t t;
 
         assert_return(ret, -EINVAL);
 
-        client = new0(sd_dhcp6_client, 1);
-        if (!client)
+        req_opts = new(be16_t, ELEMENTSOF(default_req_opts));
+        if (!req_opts)
                 return -ENOMEM;
 
-        client->n_ref = 1;
-        client->ia_na.type = SD_DHCP6_OPTION_IA_NA;
-        client->ia_pd.type = SD_DHCP6_OPTION_IA_PD;
-        client->ifindex = -1;
-        client->fd = -1;
+        for (t = 0; t < ELEMENTSOF(default_req_opts); t++)
+                req_opts[t] = htobe16(default_req_opts[t]);
 
-        client->req_opts_len = ELEMENTSOF(default_req_opts);
-        client->req_opts = new0(be16_t, client->req_opts_len);
-        if (!client->req_opts)
+        client = new(sd_dhcp6_client, 1);
+        if (!client)
                 return -ENOMEM;
 
-        for (t = 0; t < client->req_opts_len; t++)
-                client->req_opts[t] = htobe16(default_req_opts[t]);
+        *client = (sd_dhcp6_client) {
+                .n_ref = 1,
+                .ia_na.type = SD_DHCP6_OPTION_IA_NA,
+                .ia_pd.type = SD_DHCP6_OPTION_IA_PD,
+                .ifindex = -1,
+                .request = DHCP6_REQUEST_IA_NA,
+                .fd = -1,
+                .req_opts_len = ELEMENTSOF(default_req_opts),
+                .req_opts = TAKE_PTR(req_opts),
+        };
 
         *ret = TAKE_PTR(client);
 
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
index cca0b500..7263c96f 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
@@ -3,9 +3,8 @@
   Copyright © 2014-2015 Intel Corporation. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 
 #include "alloc-util.h"
 #include "dhcp6-lease-internal.h"
@@ -13,15 +12,6 @@
 #include "strv.h"
 #include "util.h"
 
-int dhcp6_lease_clear_timers(DHCP6IA *ia) {
-        assert_return(ia, -EINVAL);
-
-        ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
-        ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
-
-        return 0;
-}
-
 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
         DHCP6Address *addr;
         uint32_t valid = 0, t;
@@ -50,8 +40,6 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
         if (!ia)
                 return NULL;
 
-        dhcp6_lease_clear_timers(ia);
-
         while (ia->addresses) {
                 address = ia->addresses;
 
@@ -65,15 +53,16 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
 
 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
                              size_t len) {
+        uint8_t *serverid;
+
         assert_return(lease, -EINVAL);
         assert_return(id, -EINVAL);
 
-        free(lease->serverid);
-
-        lease->serverid = memdup(id, len);
-        if (!lease->serverid)
-                return -EINVAL;
+        serverid = memdup(id, len);
+        if (!serverid)
+                return -ENOMEM;
 
+        free_and_replace(lease->serverid, serverid);
         lease->serverid_len = len;
 
         return 0;
@@ -138,6 +127,15 @@ int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
         return 0;
 }
 
+int dhcp6_lease_get_pd_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
+        assert_return(lease, -EINVAL);
+        assert_return(iaid, -EINVAL);
+
+        *iaid = lease->pd.ia_pd.id;
+
+        return 0;
+}
+
 int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
                                uint32_t *lifetime_preferred,
                                uint32_t *lifetime_valid) {
@@ -376,27 +374,8 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
         return -ENOENT;
 }
 
-sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
-
-        if (!lease)
-                return NULL;
-
-        assert(lease->n_ref >= 1);
-        lease->n_ref++;
-
-        return lease;
-}
-
-sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
-
-        if (!lease)
-                return NULL;
-
-        assert(lease->n_ref >= 1);
-        lease->n_ref--;
-
-        if (lease->n_ref > 0)
-                return NULL;
+static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
+        assert(lease);
 
         free(lease->serverid);
         dhcp6_lease_free_ia(&lease->ia);
@@ -412,6 +391,8 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
         return mfree(lease);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_lease, sd_dhcp6_lease, dhcp6_lease_free);
+
 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
         sd_dhcp6_lease *lease;
 
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
index a39a865a..6de4adb5 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
@@ -3,10 +3,9 @@
   Copyright © 2014 Axis Communications AB. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <arpa/inet.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -16,6 +15,7 @@
 #include "alloc-util.h"
 #include "arp-util.h"
 #include "ether-addr-util.h"
+#include "event-util.h"
 #include "fd-util.h"
 #include "in-addr-util.h"
 #include "list.h"
@@ -91,7 +91,7 @@ static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_count
 static void ipv4acd_reset(sd_ipv4acd *acd) {
         assert(acd);
 
-        acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
+        (void) event_source_disable(acd->timer_event_source);
         acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source);
 
         acd->fd = safe_close(acd->fd);
@@ -99,25 +99,10 @@ static void ipv4acd_reset(sd_ipv4acd *acd) {
         ipv4acd_set_state(acd, IPV4ACD_STATE_INIT, true);
 }
 
-sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd) {
-        if (!acd)
-                return NULL;
-
-        assert_se(acd->n_ref >= 1);
-        acd->n_ref++;
-
-        return acd;
-}
-
-sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) {
-        if (!acd)
-                return NULL;
-
-        assert_se(acd->n_ref >= 1);
-        acd->n_ref--;
+static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) {
+        assert(acd);
 
-        if (acd->n_ref > 0)
-                return NULL;
+        acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
 
         ipv4acd_reset(acd);
         sd_ipv4acd_detach_event(acd);
@@ -125,19 +110,23 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) {
         return mfree(acd);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_ipv4acd, sd_ipv4acd, ipv4acd_free);
+
 int sd_ipv4acd_new(sd_ipv4acd **ret) {
         _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *acd = NULL;
 
         assert_return(ret, -EINVAL);
 
-        acd = new0(sd_ipv4acd, 1);
+        acd = new(sd_ipv4acd, 1);
         if (!acd)
                 return -ENOMEM;
 
-        acd->n_ref = 1;
-        acd->state = IPV4ACD_STATE_INIT;
-        acd->ifindex = -1;
-        acd->fd = -1;
+        *acd = (sd_ipv4acd) {
+                .n_ref = 1,
+                .state = IPV4ACD_STATE_INIT,
+                .ifindex = -1,
+                .fd = -1,
+        };
 
         *ret = TAKE_PTR(acd);
 
@@ -168,9 +157,7 @@ int sd_ipv4acd_stop(sd_ipv4acd *acd) {
 static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata);
 
 static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) {
-        _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL;
         usec_t next_timeout, time_now;
-        int r;
 
         assert(acd);
 
@@ -181,20 +168,11 @@ static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_u
 
         assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
 
-        r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(timer, acd->event_priority);
-        if (r < 0)
-                return r;
-
-        (void) sd_event_source_set_description(timer, "ipv4acd-timer");
-
-        sd_event_source_unref(acd->timer_event_source);
-        acd->timer_event_source = TAKE_PTR(timer);
-
-        return 0;
+        return event_reset_time(acd->event, &acd->timer_event_source,
+                                clock_boottime_or_monotonic(),
+                                time_now + next_timeout, 0,
+                                ipv4acd_on_timeout, acd,
+                                acd->event_priority, "ipv4acd-timer", true);
 }
 
 static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) {
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
index 69fa60e2..8b1e9665 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
@@ -3,10 +3,9 @@
   Copyright © 2014 Axis Communications AB. All rights reserved.
 ***/
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <arpa/inet.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -57,30 +56,15 @@ struct sd_ipv4ll {
 
 static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);
 
-sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
-        if (!ll)
-                return NULL;
-
-        assert(ll->n_ref >= 1);
-        ll->n_ref++;
-
-        return ll;
-}
-
-sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
-        if (!ll)
-                return NULL;
-
-        assert(ll->n_ref >= 1);
-        ll->n_ref--;
-
-        if (ll->n_ref > 0)
-                return NULL;
+static sd_ipv4ll *ipv4ll_free(sd_ipv4ll *ll) {
+        assert(ll);
 
         sd_ipv4acd_unref(ll->acd);
         return mfree(ll);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_ipv4ll, sd_ipv4ll, ipv4ll_free);
+
 int sd_ipv4ll_new(sd_ipv4ll **ret) {
         _cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL;
         int r;
diff --git a/src/systemd/src/libsystemd-network/sd-lldp.c b/src/systemd/src/libsystemd-network/sd-lldp.c
index 74ba8236..741128e1 100644
--- a/src/systemd/src/libsystemd-network/sd-lldp.c
+++ b/src/systemd/src/libsystemd-network/sd-lldp.c
@@ -1,39 +1,50 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <arpa/inet.h>
 #include <linux/sockios.h>
+#include <sys/ioctl.h>
 
 #include "sd-lldp.h"
 
 #include "alloc-util.h"
+#include "ether-addr-util.h"
+#include "event-util.h"
 #include "fd-util.h"
 #include "lldp-internal.h"
 #include "lldp-neighbor.h"
 #include "lldp-network.h"
 #include "socket-util.h"
-#include "ether-addr-util.h"
+#include "string-table.h"
 
 #define LLDP_DEFAULT_NEIGHBORS_MAX 128U
 
-static void lldp_flush_neighbors(sd_lldp *lldp) {
-        sd_lldp_neighbor *n;
+static const char * const lldp_event_table[_SD_LLDP_EVENT_MAX] = {
+        [SD_LLDP_EVENT_ADDED]   = "added",
+        [SD_LLDP_EVENT_REMOVED] = "removed",
+        [SD_LLDP_EVENT_UPDATED]   = "updated",
+        [SD_LLDP_EVENT_REFRESHED] = "refreshed",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(lldp_event, sd_lldp_event);
 
+static void lldp_flush_neighbors(sd_lldp *lldp) {
         assert(lldp);
 
-        while ((n = hashmap_first(lldp->neighbor_by_id)))
-                lldp_neighbor_unlink(n);
+        hashmap_clear(lldp->neighbor_by_id);
 }
 
 static void lldp_callback(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n) {
         assert(lldp);
+        assert(event >= 0 && event < _SD_LLDP_EVENT_MAX);
 
-        log_lldp("Invoking callback for '%c'.", event);
-
-        if (!lldp->callback)
+        if (!lldp->callback) {
+                log_lldp("Received '%s' event.", lldp_event_to_string(event));
                 return;
+        }
 
+        log_lldp("Invoking callback for '%s' event.", lldp_event_to_string(event));
         lldp->callback(lldp, event, n, lldp->userdata);
 }
 
@@ -121,7 +132,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
                 }
 
                 if (lldp_neighbor_equal(n, old)) {
-                        /* Is this equal, then restart the TTL counter, but don't do anyting else. */
+                        /* Is this equal, then restart the TTL counter, but don't do anything else. */
                         old->timestamp = n->timestamp;
                         lldp_start_timer(lldp, old);
                         lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
@@ -225,7 +236,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
 static void lldp_reset(sd_lldp *lldp) {
         assert(lldp);
 
-        lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
+        (void) event_source_disable(lldp->timer_event_source);
         lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
         lldp->fd = safe_close(lldp->fd);
 }
@@ -331,27 +342,10 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) {
         return 0;
 }
 
-_public_ sd_lldp* sd_lldp_ref(sd_lldp *lldp) {
-
-        if (!lldp)
-                return NULL;
-
-        assert(lldp->n_ref > 0);
-        lldp->n_ref++;
-
-        return lldp;
-}
-
-_public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
-
-        if (!lldp)
-                return NULL;
-
-        assert(lldp->n_ref > 0);
-        lldp->n_ref --;
+static sd_lldp* lldp_free(sd_lldp *lldp) {
+        assert(lldp);
 
-        if (lldp->n_ref > 0)
-                return NULL;
+        lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
 
         lldp_reset(lldp);
         sd_lldp_detach_event(lldp);
@@ -362,22 +356,26 @@ _public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
         return mfree(lldp);
 }
 
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_lldp, sd_lldp, lldp_free);
+
 _public_ int sd_lldp_new(sd_lldp **ret) {
         _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
 
-        lldp = new0(sd_lldp, 1);
+        lldp = new(sd_lldp, 1);
         if (!lldp)
                 return -ENOMEM;
 
-        lldp->n_ref = 1;
-        lldp->fd = -1;
-        lldp->neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX;
-        lldp->capability_mask = (uint16_t) -1;
+        *lldp = (sd_lldp) {
+                .n_ref = 1,
+                .fd = -1,
+                .neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX,
+                .capability_mask = (uint16_t) -1,
+        };
 
-        lldp->neighbor_by_id = hashmap_new(&lldp_neighbor_id_hash_ops);
+        lldp->neighbor_by_id = hashmap_new(&lldp_neighbor_hash_ops);
         if (!lldp->neighbor_by_id)
                 return -ENOMEM;
 
@@ -390,10 +388,8 @@ _public_ int sd_lldp_new(sd_lldp **ret) {
         return 0;
 }
 
-static int neighbor_compare_func(const void *a, const void *b) {
-        const sd_lldp_neighbor * const*x = a, * const *y = b;
-
-        return lldp_neighbor_id_hash_ops.compare(&(*x)->id, &(*y)->id);
+static int neighbor_compare_func(sd_lldp_neighbor * const *a, sd_lldp_neighbor * const *b) {
+        return lldp_neighbor_id_compare_func(&(*a)->id, &(*b)->id);
 }
 
 static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
@@ -413,7 +409,6 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
 
 static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
         sd_lldp_neighbor *n;
-        int r;
 
         assert(lldp);
 
@@ -421,35 +416,17 @@ static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
                 lldp_neighbor_start_ttl(neighbor);
 
         n = prioq_peek(lldp->neighbor_by_expiry);
-        if (!n) {
-
-                if (lldp->timer_event_source)
-                        return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_OFF);
-
-                return 0;
-        }
-
-        if (lldp->timer_event_source) {
-                r = sd_event_source_set_time(lldp->timer_event_source, n->until);
-                if (r < 0)
-                        return r;
-
-                return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_ONESHOT);
-        }
+        if (!n)
+                return event_source_disable(lldp->timer_event_source);
 
         if (!lldp->event)
                 return 0;
 
-        r = sd_event_add_time(lldp->event, &lldp->timer_event_source, clock_boottime_or_monotonic(), n->until, 0, on_timer_event, lldp);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(lldp->timer_event_source, lldp->event_priority);
-        if (r < 0)
-                return r;
-
-        (void) sd_event_source_set_description(lldp->timer_event_source, "lldp-timer");
-        return 0;
+        return event_reset_time(lldp->event, &lldp->timer_event_source,
+                                clock_boottime_or_monotonic(),
+                                n->until, 0,
+                                on_timer_event, lldp,
+                                lldp->event_priority, "lldp-timer", true);
 }
 
 _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
@@ -481,7 +458,7 @@ _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
         assert((size_t) k == hashmap_size(lldp->neighbor_by_id));
 
         /* Return things in a stable order */
-        qsort(l, k, sizeof(sd_lldp_neighbor*), neighbor_compare_func);
+        typesafe_qsort(l, k, neighbor_compare_func);
         *ret = l;
 
         return k;
diff --git a/src/systemd/src/libsystemd/sd-event/event-source.h b/src/systemd/src/libsystemd/sd-event/event-source.h
new file mode 100644
index 00000000..99ab8fc1
--- /dev/null
+++ b/src/systemd/src/libsystemd/sd-event/event-source.h
@@ -0,0 +1,206 @@
+#pragma once
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <sys/wait.h>
+
+#include "sd-event.h"
+
+#include "fs-util.h"
+#include "hashmap.h"
+#include "list.h"
+#include "prioq.h"
+
+typedef enum EventSourceType {
+        SOURCE_IO,
+        SOURCE_TIME_REALTIME,
+        SOURCE_TIME_BOOTTIME,
+        SOURCE_TIME_MONOTONIC,
+        SOURCE_TIME_REALTIME_ALARM,
+        SOURCE_TIME_BOOTTIME_ALARM,
+        SOURCE_SIGNAL,
+        SOURCE_CHILD,
+        SOURCE_DEFER,
+        SOURCE_POST,
+        SOURCE_EXIT,
+        SOURCE_WATCHDOG,
+        SOURCE_INOTIFY,
+        _SOURCE_EVENT_SOURCE_TYPE_MAX,
+        _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
+} EventSourceType;
+
+/* All objects we use in epoll events start with this value, so that
+ * we know how to dispatch it */
+typedef enum WakeupType {
+        WAKEUP_NONE,
+        WAKEUP_EVENT_SOURCE,
+        WAKEUP_CLOCK_DATA,
+        WAKEUP_SIGNAL_DATA,
+        WAKEUP_INOTIFY_DATA,
+        _WAKEUP_TYPE_MAX,
+        _WAKEUP_TYPE_INVALID = -1,
+} WakeupType;
+
+struct inode_data;
+
+struct sd_event_source {
+        WakeupType wakeup;
+
+        unsigned n_ref;
+
+        sd_event *event;
+        void *userdata;
+        sd_event_handler_t prepare;
+
+        char *description;
+
+        EventSourceType type:5;
+        signed int enabled:3;
+        bool pending:1;
+        bool dispatching:1;
+        bool floating:1;
+
+        int64_t priority;
+        unsigned pending_index;
+        unsigned prepare_index;
+        uint64_t pending_iteration;
+        uint64_t prepare_iteration;
+
+        sd_event_destroy_t destroy_callback;
+
+        LIST_FIELDS(sd_event_source, sources);
+
+        union {
+                struct {
+                        sd_event_io_handler_t callback;
+                        int fd;
+                        uint32_t events;
+                        uint32_t revents;
+                        bool registered:1;
+                        bool owned:1;
+                } io;
+                struct {
+                        sd_event_time_handler_t callback;
+                        usec_t next, accuracy;
+                        unsigned earliest_index;
+                        unsigned latest_index;
+                } time;
+                struct {
+                        sd_event_signal_handler_t callback;
+                        struct signalfd_siginfo siginfo;
+                        int sig;
+                } signal;
+                struct {
+                        sd_event_child_handler_t callback;
+                        siginfo_t siginfo;
+                        pid_t pid;
+                        int options;
+                } child;
+                struct {
+                        sd_event_handler_t callback;
+                } defer;
+                struct {
+                        sd_event_handler_t callback;
+                } post;
+                struct {
+                        sd_event_handler_t callback;
+                        unsigned prioq_index;
+                } exit;
+                struct {
+                        sd_event_inotify_handler_t callback;
+                        uint32_t mask;
+                        struct inode_data *inode_data;
+                        LIST_FIELDS(sd_event_source, by_inode_data);
+                } inotify;
+        };
+};
+
+struct clock_data {
+        WakeupType wakeup;
+        int fd;
+
+        /* For all clocks we maintain two priority queues each, one
+         * ordered for the earliest times the events may be
+         * dispatched, and one ordered by the latest times they must
+         * have been dispatched. The range between the top entries in
+         * the two prioqs is the time window we can freely schedule
+         * wakeups in */
+
+        Prioq *earliest;
+        Prioq *latest;
+        usec_t next;
+
+        bool needs_rearm:1;
+};
+
+struct signal_data {
+        WakeupType wakeup;
+
+        /* For each priority we maintain one signal fd, so that we
+         * only have to dequeue a single event per priority at a
+         * time. */
+
+        int fd;
+        int64_t priority;
+        sigset_t sigset;
+        sd_event_source *current;
+};
+
+/* A structure listing all event sources currently watching a specific inode */
+struct inode_data {
+        /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */
+        ino_t ino;
+        dev_t dev;
+
+        /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
+         * rearrange the priority still until then, as we need the original inode to change the priority as we need to
+         * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
+         * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
+         * the sd-event object, so that it is efficient to close everything, before entering the next event loop
+         * iteration. */
+        int fd;
+
+        /* The inotify "watch descriptor" */
+        int wd;
+
+        /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has
+         * most recently been set on the watch descriptor. */
+        uint32_t combined_mask;
+
+        /* All event sources subscribed to this inode */
+        LIST_HEAD(sd_event_source, event_sources);
+
+        /* The inotify object we watch this inode with */
+        struct inotify_data *inotify_data;
+
+        /* A linked list of all inode data objects with fds to close (see above) */
+        LIST_FIELDS(struct inode_data, to_close);
+};
+
+/* A structure encapsulating an inotify fd */
+struct inotify_data {
+        WakeupType wakeup;
+
+        /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at
+         * a time */
+
+        int fd;
+        int64_t priority;
+
+        Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
+        Hashmap *wd;     /* The inode_data structures keyed by the watch descriptor for each */
+
+        /* The buffer we read inotify events into */
+        union inotify_event_buffer buffer;
+        size_t buffer_filled; /* fill level of the buffer */
+
+        /* How many event sources are currently marked pending for this inotify. We won't read new events off the
+         * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
+         * the events locally if they can't be coalesced). */
+        unsigned n_pending;
+
+        /* A linked list of all inotify objects with data already read, that still need processing. We keep this list
+         * to make it efficient to figure out what inotify objects to process data on next. */
+        LIST_FIELDS(struct inotify_data, buffered);
+};
diff --git a/src/systemd/src/libsystemd/sd-event/event-util.c b/src/systemd/src/libsystemd/sd-event/event-util.c
new file mode 100644
index 00000000..2afacfe6
--- /dev/null
+++ b/src/systemd/src/libsystemd/sd-event/event-util.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "nm-sd-adapt-core.h"
+
+
+#include "event-source.h"
+#include "event-util.h"
+#include "log.h"
+#include "string-util.h"
+
+int event_reset_time(
+                sd_event *e,
+                sd_event_source **s,
+                clockid_t clock,
+                uint64_t usec,
+                uint64_t accuracy,
+                sd_event_time_handler_t callback,
+                void *userdata,
+                int64_t priority,
+                const char *description,
+                bool force_reset) {
+
+        bool created = false;
+        int enabled, r;
+        clockid_t c;
+
+        assert(e);
+        assert(s);
+
+        if (*s) {
+                if (!force_reset) {
+                        r = sd_event_source_get_enabled(*s, &enabled);
+                        if (r < 0)
+                                return log_debug_errno(r, "sd-event: Failed to query whether event source \"%s\" is enabled or not: %m",
+                                                       strna((*s)->description ?: description));
+
+                        if (enabled != SD_EVENT_OFF)
+                                return 0;
+                }
+
+                r = sd_event_source_get_time_clock(*s, &c);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to get clock id of event source \"%s\": %m", strna((*s)->description ?: description));
+
+                if (c != clock)
+                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "sd-event: Current clock id %i of event source \"%s\" is different from specified one %i.",
+                                               (int)c,
+                                               strna((*s)->description ? : description),
+                                               (int)clock);
+
+                r = sd_event_source_set_time(*s, usec);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to set time for event source \"%s\": %m", strna((*s)->description ?: description));
+
+                r = sd_event_source_set_time_accuracy(*s, accuracy);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to set accuracy for event source \"%s\": %m", strna((*s)->description ?: description));
+
+                /* callback function is not updated, as we do not have sd_event_source_set_time_callback(). */
+
+                (void) sd_event_source_set_userdata(*s, userdata);
+
+                r = sd_event_source_set_enabled(*s, SD_EVENT_ONESHOT);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to enable event source \"%s\": %m", strna((*s)->description ?: description));
+        } else {
+                r = sd_event_add_time(e, s, clock, usec, accuracy, callback, userdata);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to create timer event \"%s\": %m", strna(description));
+
+                created = true;
+        }
+
+        r = sd_event_source_set_priority(*s, priority);
+        if (r < 0)
+                return log_debug_errno(r, "sd-event: Failed to set priority for event source \"%s\": %m", strna((*s)->description ?: description));
+
+        if (description) {
+                r = sd_event_source_set_description(*s, description);
+                if (r < 0)
+                        return log_debug_errno(r, "sd-event: Failed to set description for event source \"%s\": %m", description);
+        }
+
+        return created;
+}
+
+int event_source_disable(sd_event_source *s) {
+        if (!s)
+                return 0;
+
+        return sd_event_source_set_enabled(s, SD_EVENT_OFF);
+}
+
+int event_source_is_enabled(sd_event_source *s) {
+        if (!s)
+                return false;
+
+        return sd_event_source_get_enabled(s, NULL);
+}
diff --git a/src/systemd/src/libsystemd/sd-event/event-util.h b/src/systemd/src/libsystemd/sd-event/event-util.h
new file mode 100644
index 00000000..00180955
--- /dev/null
+++ b/src/systemd/src/libsystemd/sd-event/event-util.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "sd-event.h"
+
+int event_reset_time(sd_event *e, sd_event_source **s,
+                     clockid_t clock, uint64_t usec, uint64_t accuracy,
+                     sd_event_time_handler_t callback, void *userdata,
+                     int64_t priority, const char *description, bool force_reset);
+int event_source_disable(sd_event_source *s);
+int event_source_is_enabled(sd_event_source *s);
diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c
index 2af3572d..6f77421b 100644
--- a/src/systemd/src/libsystemd/sd-event/sd-event.c
+++ b/src/systemd/src/libsystemd/sd-event/sd-event.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #include <sys/epoll.h>
 #include <sys/timerfd.h>
@@ -11,6 +11,7 @@
 #include "sd-id128.h"
 
 #include "alloc-util.h"
+#include "event-source.h"
 #include "fd-util.h"
 #include "fs-util.h"
 #include "hashmap.h"
@@ -28,24 +29,6 @@
 
 #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
 
-typedef enum EventSourceType {
-        SOURCE_IO,
-        SOURCE_TIME_REALTIME,
-        SOURCE_TIME_BOOTTIME,
-        SOURCE_TIME_MONOTONIC,
-        SOURCE_TIME_REALTIME_ALARM,
-        SOURCE_TIME_BOOTTIME_ALARM,
-        SOURCE_SIGNAL,
-        SOURCE_CHILD,
-        SOURCE_DEFER,
-        SOURCE_POST,
-        SOURCE_EXIT,
-        SOURCE_WATCHDOG,
-        SOURCE_INOTIFY,
-        _SOURCE_EVENT_SOURCE_TYPE_MAX,
-        _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
-} EventSourceType;
-
 static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
         [SOURCE_IO] = "io",
         [SOURCE_TIME_REALTIME] = "realtime",
@@ -64,183 +47,8 @@ static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX]
 
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
 
-/* All objects we use in epoll events start with this value, so that
- * we know how to dispatch it */
-typedef enum WakeupType {
-        WAKEUP_NONE,
-        WAKEUP_EVENT_SOURCE,
-        WAKEUP_CLOCK_DATA,
-        WAKEUP_SIGNAL_DATA,
-        WAKEUP_INOTIFY_DATA,
-        _WAKEUP_TYPE_MAX,
-        _WAKEUP_TYPE_INVALID = -1,
-} WakeupType;
-
 #define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
 
-struct inode_data;
-
-struct sd_event_source {
-        WakeupType wakeup;
-
-        unsigned n_ref;
-
-        sd_event *event;
-        void *userdata;
-        sd_event_handler_t prepare;
-
-        char *description;
-
-        EventSourceType type:5;
-        signed int enabled:3;
-        bool pending:1;
-        bool dispatching:1;
-        bool floating:1;
-
-        int64_t priority;
-        unsigned pending_index;
-        unsigned prepare_index;
-        uint64_t pending_iteration;
-        uint64_t prepare_iteration;
-
-        sd_event_destroy_t destroy_callback;
-
-        LIST_FIELDS(sd_event_source, sources);
-
-        union {
-                struct {
-                        sd_event_io_handler_t callback;
-                        int fd;
-                        uint32_t events;
-                        uint32_t revents;
-                        bool registered:1;
-                        bool owned:1;
-                } io;
-                struct {
-                        sd_event_time_handler_t callback;
-                        usec_t next, accuracy;
-                        unsigned earliest_index;
-                        unsigned latest_index;
-                } time;
-                struct {
-                        sd_event_signal_handler_t callback;
-                        struct signalfd_siginfo siginfo;
-                        int sig;
-                } signal;
-                struct {
-                        sd_event_child_handler_t callback;
-                        siginfo_t siginfo;
-                        pid_t pid;
-                        int options;
-                } child;
-                struct {
-                        sd_event_handler_t callback;
-                } defer;
-                struct {
-                        sd_event_handler_t callback;
-                } post;
-                struct {
-                        sd_event_handler_t callback;
-                        unsigned prioq_index;
-                } exit;
-                struct {
-                        sd_event_inotify_handler_t callback;
-                        uint32_t mask;
-                        struct inode_data *inode_data;
-                        LIST_FIELDS(sd_event_source, by_inode_data);
-                } inotify;
-        };
-};
-
-struct clock_data {
-        WakeupType wakeup;
-        int fd;
-
-        /* For all clocks we maintain two priority queues each, one
-         * ordered for the earliest times the events may be
-         * dispatched, and one ordered by the latest times they must
-         * have been dispatched. The range between the top entries in
-         * the two prioqs is the time window we can freely schedule
-         * wakeups in */
-
-        Prioq *earliest;
-        Prioq *latest;
-        usec_t next;
-
-        bool needs_rearm:1;
-};
-
-struct signal_data {
-        WakeupType wakeup;
-
-        /* For each priority we maintain one signal fd, so that we
-         * only have to dequeue a single event per priority at a
-         * time. */
-
-        int fd;
-        int64_t priority;
-        sigset_t sigset;
-        sd_event_source *current;
-};
-
-/* A structure listing all event sources currently watching a specific inode */
-struct inode_data {
-        /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */
-        ino_t ino;
-        dev_t dev;
-
-        /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
-         * rearrange the priority still until then, as we need the original inode to change the priority as we need to
-         * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
-         * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
-         * the sd-event object, so that it is efficient to close everything, before entering the next event loop
-         * iteration. */
-        int fd;
-
-        /* The inotify "watch descriptor" */
-        int wd;
-
-        /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has
-         * most recently been set on the watch descriptor. */
-        uint32_t combined_mask;
-
-        /* All event sources subscribed to this inode */
-        LIST_HEAD(sd_event_source, event_sources);
-
-        /* The inotify object we watch this inode with */
-        struct inotify_data *inotify_data;
-
-        /* A linked list of all inode data objects with fds to close (see above) */
-        LIST_FIELDS(struct inode_data, to_close);
-};
-
-/* A structure encapsulating an inotify fd */
-struct inotify_data {
-        WakeupType wakeup;
-
-        /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at
-         * a time */
-
-        int fd;
-        int64_t priority;
-
-        Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
-        Hashmap *wd;     /* The inode_data structures keyed by the watch descriptor for each */
-
-        /* The buffer we read inotify events into */
-        union inotify_event_buffer buffer;
-        size_t buffer_filled; /* fill level of the buffer */
-
-        /* How many event sources are currently marked pending for this inotify. We won't read new events off the
-         * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
-         * the events locally if they can't be coalesced). */
-        unsigned n_pending;
-
-        /* A linked list of all inotify objects with data already read, that still need processing. We keep this list
-         * to make it efficient to figure out what inotify objects to process data on next. */
-        LIST_FIELDS(struct inotify_data, buffered);
-};
-
 struct sd_event {
         unsigned n_ref;
 
@@ -316,6 +124,7 @@ static sd_event *event_resolve(sd_event *e) {
 
 static int pending_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
+        int r;
 
         assert(x->pending);
         assert(y->pending);
@@ -327,22 +136,17 @@ static int pending_prioq_compare(const void *a, const void *b) {
                 return 1;
 
         /* Lower priority values first */
-        if (x->priority < y->priority)
-                return -1;
-        if (x->priority > y->priority)
-                return 1;
+        r = CMP(x->priority, y->priority);
+        if (r != 0)
+                return r;
 
         /* Older entries first */
-        if (x->pending_iteration < y->pending_iteration)
-                return -1;
-        if (x->pending_iteration > y->pending_iteration)
-                return 1;
-
-        return 0;
+        return CMP(x->pending_iteration, y->pending_iteration);
 }
 
 static int prepare_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
+        int r;
 
         assert(x->prepare);
         assert(y->prepare);
@@ -356,18 +160,12 @@ static int prepare_prioq_compare(const void *a, const void *b) {
         /* Move most recently prepared ones last, so that we can stop
          * preparing as soon as we hit one that has already been
          * prepared in the current iteration */
-        if (x->prepare_iteration < y->prepare_iteration)
-                return -1;
-        if (x->prepare_iteration > y->prepare_iteration)
-                return 1;
+        r = CMP(x->prepare_iteration, y->prepare_iteration);
+        if (r != 0)
+                return r;
 
         /* Lower priority values first */
-        if (x->priority < y->priority)
-                return -1;
-        if (x->priority > y->priority)
-                return 1;
-
-        return 0;
+        return CMP(x->priority, y->priority);
 }
 
 static int earliest_time_prioq_compare(const void *a, const void *b) {
@@ -389,12 +187,7 @@ static int earliest_time_prioq_compare(const void *a, const void *b) {
                 return 1;
 
         /* Order by time */
-        if (x->time.next < y->time.next)
-                return -1;
-        if (x->time.next > y->time.next)
-                return 1;
-
-        return 0;
+        return CMP(x->time.next, y->time.next);
 }
 
 static usec_t time_event_source_latest(const sd_event_source *s) {
@@ -420,12 +213,7 @@ static int latest_time_prioq_compare(const void *a, const void *b) {
                 return 1;
 
         /* Order by time */
-        if (time_event_source_latest(x) < time_event_source_latest(y))
-                return -1;
-        if (time_event_source_latest(x) > time_event_source_latest(y))
-                return 1;
-
-        return 0;
+        return CMP(time_event_source_latest(x), time_event_source_latest(y));
 }
 
 static int exit_prioq_compare(const void *a, const void *b) {
@@ -441,12 +229,7 @@ static int exit_prioq_compare(const void *a, const void *b) {
                 return 1;
 
         /* Lower priority values first */
-        if (x->priority < y->priority)
-                return -1;
-        if (x->priority > y->priority)
-                return 1;
-
-        return 0;
+        return CMP(x->priority, y->priority);
 }
 
 static void free_clock_data(struct clock_data *d) {
@@ -458,7 +241,7 @@ static void free_clock_data(struct clock_data *d) {
         prioq_free(d->latest);
 }
 
-static void event_free(sd_event *e) {
+static sd_event *event_free(sd_event *e) {
         sd_event_source *s;
 
         assert(e);
@@ -494,7 +277,8 @@ static void event_free(sd_event *e) {
 
         hashmap_free(e->child_sources);
         set_free(e->post_sources);
-        free(e);
+
+        return mfree(e);
 }
 
 _public_ int sd_event_new(sd_event** ret) {
@@ -555,30 +339,7 @@ fail:
         return r;
 }
 
-_public_ sd_event* sd_event_ref(sd_event *e) {
-
-        if (!e)
-                return NULL;
-
-        assert(e->n_ref >= 1);
-        e->n_ref++;
-
-        return e;
-}
-
-_public_ sd_event* sd_event_unref(sd_event *e) {
-
-        if (!e)
-                return NULL;
-
-        assert(e->n_ref >= 1);
-        e->n_ref--;
-
-        if (e->n_ref <= 0)
-                event_free(e);
-
-        return NULL;
-}
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event, sd_event, event_free);
 
 static bool event_pid_changed(sd_event *e) {
         assert(e);
@@ -711,6 +472,17 @@ static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
         }
 }
 
+static void event_free_signal_data(sd_event *e, struct signal_data *d) {
+        assert(e);
+
+        if (!d)
+                return;
+
+        hashmap_remove(e->signal_data, &d->priority);
+        safe_close(d->fd);
+        free(d);
+}
+
 static int event_make_signal_data(
                 sd_event *e,
                 int sig,
@@ -800,11 +572,8 @@ static int event_make_signal_data(
         return 0;
 
 fail:
-        if (added) {
-                d->fd = safe_close(d->fd);
-                hashmap_remove(e->signal_data, &d->priority);
-                free(d);
-        }
+        if (added)
+                event_free_signal_data(e, d);
 
         return r;
 }
@@ -823,11 +592,8 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
         assert_se(sigdelset(&d->sigset, sig) >= 0);
 
         if (sigisemptyset(&d->sigset)) {
-
                 /* If all the mask is all-zero we can get rid of the structure */
-                hashmap_remove(e->signal_data, &d->priority);
-                safe_close(d->fd);
-                free(d);
+                event_free_signal_data(e, d);
                 return;
         }
 
@@ -974,7 +740,7 @@ static void source_disconnect(sd_event_source *s) {
                          * continued to being watched. That's because inotify doesn't really have an API for that: we
                          * can only change watch masks with access to the original inode either by fd or by path. But
                          * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd
-                         * continously and keeping the mount busy which we can't really do. We could reconstruct the
+                         * continuously and keeping the mount busy which we can't really do. We could reconstruct the
                          * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed
                          * there), but given the need for open_by_handle_at() which is privileged and not universally
                          * available this would be quite an incomplete solution. Hence we go the other way, leave the
@@ -1023,6 +789,7 @@ static void source_free(sd_event_source *s) {
         free(s->description);
         free(s);
 }
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free);
 
 static int source_set_pending(sd_event_source *s, bool b) {
         int r;
@@ -1116,7 +883,7 @@ _public_ int sd_event_add_io(
                 sd_event_io_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1139,13 +906,12 @@ _public_ int sd_event_add_io(
         s->enabled = SD_EVENT_ON;
 
         r = source_io_register(s, s->enabled, events);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1154,7 +920,7 @@ static void initialize_perturb(sd_event *e) {
         sd_id128_t bootid = {};
 
         /* When we sleep for longer, we try to realign the wakeup to
-           the same time wihtin each minute/second/250ms, so that
+           the same time within each minute/second/250ms, so that
            events all across the system can be coalesced into a single
            CPU wakeup. However, let's take some system-specific
            randomness for this value, so that in a network of systems
@@ -1220,7 +986,7 @@ _public_ int sd_event_add_time(
                 void *userdata) {
 
         EventSourceType type;
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct clock_data *d;
         int r;
 
@@ -1272,20 +1038,17 @@ _public_ int sd_event_add_time(
 
         r = prioq_put(d->earliest, s, &s->time.earliest_index);
         if (r < 0)
-                goto fail;
+                return r;
 
         r = prioq_put(d->latest, s, &s->time.latest_index);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
-
-fail:
-        source_free(s);
-        return r;
 }
 
 #if 0 /* NM_IGNORED */
@@ -1302,7 +1065,7 @@ _public_ int sd_event_add_signal(
                 sd_event_signal_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct signal_data *d;
         sigset_t ss;
         int r;
@@ -1342,16 +1105,15 @@ _public_ int sd_event_add_signal(
         e->signal_sources[sig] = s;
 
         r = event_make_signal_data(e, sig, &d);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         /* Use the signal name as description for the event source by default */
         (void) sd_event_source_set_description(s, signal_to_string(sig));
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1365,7 +1127,7 @@ _public_ int sd_event_add_child(
                 sd_event_child_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1395,17 +1157,14 @@ _public_ int sd_event_add_child(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         e->n_enabled_child_sources++;
 
         r = event_make_signal_data(e, SIGCHLD, NULL);
         if (r < 0) {
                 e->n_enabled_child_sources--;
-                source_free(s);
                 return r;
         }
 
@@ -1413,6 +1172,7 @@ _public_ int sd_event_add_child(
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1423,7 +1183,7 @@ _public_ int sd_event_add_defer(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1441,13 +1201,12 @@ _public_ int sd_event_add_defer(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = source_set_pending(s, true);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1458,7 +1217,7 @@ _public_ int sd_event_add_post(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1480,13 +1239,12 @@ _public_ int sd_event_add_post(
         s->enabled = SD_EVENT_ON;
 
         r = set_put(e->post_sources, s);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1497,7 +1255,7 @@ _public_ int sd_event_add_exit(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1520,13 +1278,12 @@ _public_ int sd_event_add_exit(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1623,38 +1380,27 @@ static int event_make_inotify_data(
         return 1;
 }
 
-static int inode_data_compare(const void *a, const void *b) {
-        const struct inode_data *x = a, *y = b;
+static int inode_data_compare(const struct inode_data *x, const struct inode_data *y) {
+        int r;
 
         assert(x);
         assert(y);
 
-        if (x->dev < y->dev)
-                return -1;
-        if (x->dev > y->dev)
-                return 1;
-
-        if (x->ino < y->ino)
-                return -1;
-        if (x->ino > y->ino)
-                return 1;
+        r = CMP(x->dev, y->dev);
+        if (r != 0)
+                return r;
 
-        return 0;
+        return CMP(x->ino, y->ino);
 }
 
-static void inode_data_hash_func(const void *p, struct siphash *state) {
-        const struct inode_data *d = p;
-
-        assert(p);
+static void inode_data_hash_func(const struct inode_data *d, struct siphash *state) {
+        assert(d);
 
         siphash24_compress(&d->dev, sizeof(d->dev), state);
         siphash24_compress(&d->ino, sizeof(d->ino), state);
 }
 
-const struct hash_ops inode_data_hash_ops = {
-        .hash = inode_data_hash_func,
-        .compare = inode_data_compare
-};
+DEFINE_PRIVATE_HASH_OPS(inode_data_hash_ops, struct inode_data, inode_data_hash_func, inode_data_compare);
 
 static void event_free_inode_data(
                 sd_event *e,
@@ -1781,7 +1527,7 @@ static uint32_t inode_data_determine_mask(struct inode_data *d) {
          *
          * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's
          * because we cannot change the mask anymore after the event source was created once, since the kernel has no
-         * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and supress
+         * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and suppress
          * events we don't care for client-side. */
 
         LIST_FOREACH(inotify.by_inode_data, s, d->event_sources) {
@@ -1843,11 +1589,10 @@ _public_ int sd_event_add_inotify(
                 sd_event_inotify_handler_t callback,
                 void *userdata) {
 
-        bool rm_inotify = false, rm_inode = false;
         struct inotify_data *inotify_data = NULL;
         struct inode_data *inode_data = NULL;
         _cleanup_close_ int fd = -1;
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct stat st;
         int r;
 
@@ -1885,13 +1630,13 @@ _public_ int sd_event_add_inotify(
         /* Allocate an inotify object for this priority, and an inode object within it */
         r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data);
         if (r < 0)
-                goto fail;
-        rm_inotify = r > 0;
+                return r;
 
         r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data);
-        if (r < 0)
-                goto fail;
-        rm_inode = r > 0;
+        if (r < 0) {
+                event_free_inotify_data(e, inotify_data);
+                return r;
+        }
 
         /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of
          * the event source, until then, for which we need the original inode. */
@@ -1904,72 +1649,45 @@ _public_ int sd_event_add_inotify(
         LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s);
         s->inotify.inode_data = inode_data;
 
-        rm_inode = rm_inotify = false;
-
         /* Actually realize the watch now */
         r = inode_data_realize_watch(e, inode_data);
         if (r < 0)
-                goto fail;
+                return r;
 
         (void) sd_event_source_set_description(s, path);
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
-
-fail:
-        source_free(s);
-
-        if (rm_inode)
-                event_free_inode_data(e, inode_data);
-
-        if (rm_inotify)
-                event_free_inotify_data(e, inotify_data);
-
-        return r;
 }
 
-_public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
-
+static sd_event_source* event_source_free(sd_event_source *s) {
         if (!s)
                 return NULL;
 
-        assert(s->n_ref >= 1);
-        s->n_ref++;
-
-        return s;
-}
-
-_public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
+        /* Here's a special hack: when we are called from a
+         * dispatch handler we won't free the event source
+         * immediately, but we will detach the fd from the
+         * epoll. This way it is safe for the caller to unref
+         * the event source and immediately close the fd, but
+         * we still retain a valid event source object after
+         * the callback. */
 
-        if (!s)
-                return NULL;
-
-        assert(s->n_ref >= 1);
-        s->n_ref--;
-
-        if (s->n_ref <= 0) {
-                /* Here's a special hack: when we are called from a
-                 * dispatch handler we won't free the event source
-                 * immediately, but we will detach the fd from the
-                 * epoll. This way it is safe for the caller to unref
-                 * the event source and immediately close the fd, but
-                 * we still retain a valid event source object after
-                 * the callback. */
-
-                if (s->dispatching) {
-                        if (s->type == SOURCE_IO)
-                                source_io_unregister(s);
+        if (s->dispatching) {
+                if (s->type == SOURCE_IO)
+                        source_io_unregister(s);
 
-                        source_disconnect(s);
-                } else
-                        source_free(s);
-        }
+                source_disconnect(s);
+        } else
+                source_free(s);
 
         return NULL;
 }
 
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event_source, sd_event_source, event_source_free);
+
 _public_ int sd_event_source_set_description(sd_event_source *s, const char *description) {
         assert_return(s, -EINVAL);
         assert_return(!event_pid_changed(s->event), -ECHILD);
@@ -1980,9 +1698,11 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des
 _public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
         assert_return(s, -EINVAL);
         assert_return(description, -EINVAL);
-        assert_return(s->description, -ENXIO);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
+        if (!s->description)
+                return -ENXIO;
+
         *description = s->description;
         return 0;
 }
@@ -2234,11 +1954,11 @@ fail:
 
 _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
         assert_return(s, -EINVAL);
-        assert_return(m, -EINVAL);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
-        *m = s->enabled;
-        return 0;
+        if (m)
+                *m = s->enabled;
+        return s->enabled != SD_EVENT_OFF;
 }
 
 _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
@@ -3796,4 +3516,32 @@ _public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_d
 
         return !!s->destroy_callback;
 }
+
+_public_ int sd_event_source_get_floating(sd_event_source *s) {
+        assert_return(s, -EINVAL);
+
+        return s->floating;
+}
+
+_public_ int sd_event_source_set_floating(sd_event_source *s, int b) {
+        assert_return(s, -EINVAL);
+
+        if (s->floating == !!b)
+                return 0;
+
+        if (!s->event) /* Already disconnected */
+                return -ESTALE;
+
+        s->floating = b;
+
+        if (b) {
+                sd_event_source_ref(s);
+                sd_event_unref(s->event);
+        } else {
+                sd_event_ref(s->event);
+                sd_event_source_unref(s);
+        }
+
+        return 1;
+}
 #endif /* NM_IGNORED */
diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.c b/src/systemd/src/libsystemd/sd-id128/id128-util.c
index d4d668e8..6245e9df 100644
--- a/src/systemd/src/libsystemd/sd-id128/id128-util.c
+++ b/src/systemd/src/libsystemd/sd-id128/id128-util.c
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -187,16 +186,13 @@ int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {
         return id128_write_fd(fd, f, id, do_sync);
 }
 
-void id128_hash_func(const void *p, struct siphash *state) {
-        siphash24_compress(p, 16, state);
+void id128_hash_func(const sd_id128_t *p, struct siphash *state) {
+        siphash24_compress(p, sizeof(sd_id128_t), state);
 }
 
-int id128_compare_func(const void *a, const void *b) {
+int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) {
         return memcmp(a, b, 16);
 }
 
-const struct hash_ops id128_hash_ops = {
-        .hash = id128_hash_func,
-        .compare = id128_compare_func,
-};
+DEFINE_HASH_OPS(id128_hash_ops, sd_id128_t, id128_hash_func, id128_compare_func);
 #endif /* NM_IGNORED */
diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.h b/src/systemd/src/libsystemd/sd-id128/id128-util.h
index 44f159c0..65f14ab2 100644
--- a/src/systemd/src/libsystemd/sd-id128/id128-util.h
+++ b/src/systemd/src/libsystemd/sd-id128/id128-util.h
@@ -28,6 +28,6 @@ int id128_read(const char *p, Id128Format f, sd_id128_t *ret);
 int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync);
 int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
 
-void id128_hash_func(const void *p, struct siphash *state);
-int id128_compare_func(const void *a, const void *b) _pure_;
+void id128_hash_func(const sd_id128_t *p, struct siphash *state);
+int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
 extern const struct hash_ops id128_hash_ops;
diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
index 483b2fe0..13a28291 100644
--- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -21,7 +20,7 @@
 #include "util.h"
 
 #if 0 /* NM_IGNORED */
-_public_ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]) {
+_public_ char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]) {
         unsigned n;
 
         assert_return(s, NULL);
@@ -277,7 +276,9 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
 
         assert_return(ret, -EINVAL);
 
-        r = acquire_random_bytes(&t, sizeof t, true);
+        /* We allow usage if x86-64 RDRAND here. It might not be trusted enough for keeping secrets, but it should be
+         * fine for UUIDS. */
+        r = genuine_random_bytes(&t, sizeof t, RANDOM_ALLOW_RDRAND);
         if (r < 0)
                 return r;
 
@@ -289,19 +290,15 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
         return 0;
 }
 
-_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+static int get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) {
         _cleanup_(khash_unrefp) khash *h = NULL;
-        sd_id128_t m, result;
+        sd_id128_t result;
         const void *p;
         int r;
 
-        assert_return(ret, -EINVAL);
-
-        r = sd_id128_get_machine(&m);
-        if (r < 0)
-                return r;
+        assert(ret);
 
-        r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m));
+        r = khash_new_with_key(&h, "hmac(sha256)", &base, sizeof(base));
         if (r < 0)
                 return r;
 
@@ -319,4 +316,30 @@ _public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *re
         *ret = make_v4_uuid(result);
         return 0;
 }
+
+_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+        sd_id128_t id;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_id128_get_machine(&id);
+        if (r < 0)
+                return r;
+
+        return get_app_specific(id, app_id, ret);
+}
+
+_public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+        sd_id128_t id;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_id128_get_boot(&id);
+        if (r < 0)
+                return r;
+
+        return get_app_specific(id, app_id, ret);
+}
 #endif /* NM_IGNORED */
diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c
index 048075f2..ebea861f 100644
--- a/src/systemd/src/shared/dns-domain.c
+++ b/src/systemd/src/shared/dns-domain.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include "nm-sd-adapt.h"
+#include "nm-sd-adapt-core.h"
 
 #if 0 /* NM_IGNORED */
 #if HAVE_LIBIDN2
@@ -21,6 +21,7 @@
 #include "dns-domain.h"
 #include "hashmap.h"
 #include "hexdecoct.h"
+#include "hostname-util.h"
 #include "in-addr-util.h"
 #include "macro.h"
 #include "parse-util.h"
@@ -28,9 +29,9 @@
 #include "strv.h"
 #include "utf8.h"
 
-int dns_label_unescape(const char **name, char *dest, size_t sz) {
+int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags) {
         const char *n;
-        char *d;
+        char *d, last_char = 0;
         int r = 0;
 
         assert(name);
@@ -40,13 +41,15 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
         d = dest;
 
         for (;;) {
-                if (*n == '.') {
-                        n++;
-                        break;
-                }
+                if (*n == 0 || *n == '.') {
+                        if (FLAGS_SET(flags, DNS_LABEL_LDH) && last_char == '-')
+                                /* Trailing dash */
+                                return -EINVAL;
 
-                if (*n == 0)
+                        if (*n == '.')
+                                n++;
                         break;
+                }
 
                 if (r >= DNS_LABEL_MAX)
                         return -EINVAL;
@@ -56,6 +59,8 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
 
                 if (*n == '\\') {
                         /* Escaped character */
+                        if (FLAGS_SET(flags, DNS_LABEL_NO_ESCAPES))
+                                return -EINVAL;
 
                         n++;
 
@@ -66,6 +71,10 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
                         else if (IN_SET(*n, '\\', '.')) {
                                 /* Escaped backslash or dot */
 
+                                if (FLAGS_SET(flags, DNS_LABEL_LDH))
+                                        return -EINVAL;
+
+                                last_char = *n;
                                 if (d)
                                         *(d++) = *n;
                                 sz--;
@@ -94,6 +103,11 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
                                 if (k > 255)
                                         return -EINVAL;
 
+                                if (FLAGS_SET(flags, DNS_LABEL_LDH) &&
+                                    !valid_ldh_char((char) k))
+                                        return -EINVAL;
+
+                                last_char = (char) k;
                                 if (d)
                                         *(d++) = (char) k;
                                 sz--;
@@ -107,6 +121,15 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
 
                         /* Normal character */
 
+                        if (FLAGS_SET(flags, DNS_LABEL_LDH)) {
+                                if (!valid_ldh_char(*n))
+                                        return -EINVAL;
+                                if (r == 0 && *n == '-')
+                                        /* Leading dash */
+                                        return -EINVAL;
+                        }
+
+                        last_char = *n;
                         if (d)
                                 *(d++) = *n;
                         sz--;
@@ -189,7 +212,7 @@ int dns_label_unescape_suffix(const char *name, const char **label_terminal, cha
                 terminal--;
         }
 
-        r = dns_label_unescape(&name, dest, sz);
+        r = dns_label_unescape(&name, dest, sz, 0);
         if (r < 0)
                 return r;
 
@@ -386,7 +409,7 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
 #endif
 #endif /* NM_IGNORED */
 
-int dns_name_concat(const char *a, const char *b, char **_ret) {
+int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) {
         _cleanup_free_ char *ret = NULL;
         size_t n = 0, allocated = 0;
         const char *p;
@@ -403,7 +426,7 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
         for (;;) {
                 char label[DNS_LABEL_MAX];
 
-                r = dns_label_unescape(&p, label, sizeof(label));
+                r = dns_label_unescape(&p, label, sizeof label, flags);
                 if (r < 0)
                         return r;
                 if (r == 0) {
@@ -469,8 +492,7 @@ finish:
 }
 
 #if 0 /* NM_IGNORED */
-void dns_name_hash_func(const void *s, struct siphash *state) {
-        const char *p = s;
+void dns_name_hash_func(const char *p, struct siphash *state) {
         int r;
 
         assert(p);
@@ -478,7 +500,7 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
         for (;;) {
                 char label[DNS_LABEL_MAX+1];
 
-                r = dns_label_unescape(&p, label, sizeof(label));
+                r = dns_label_unescape(&p, label, sizeof label, 0);
                 if (r < 0)
                         break;
                 if (r == 0)
@@ -493,15 +515,15 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
         string_hash_func("", state);
 }
 
-int dns_name_compare_func(const void *a, const void *b) {
+int dns_name_compare_func(const char *a, const char *b) {
         const char *x, *y;
         int r, q;
 
         assert(a);
         assert(b);
 
-        x = (const char *) a + strlen(a);
-        y = (const char *) b + strlen(b);
+        x = a + strlen(a);
+        y = b + strlen(b);
 
         for (;;) {
                 char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
@@ -520,10 +542,7 @@ int dns_name_compare_func(const void *a, const void *b) {
         }
 }
 
-const struct hash_ops dns_name_hash_ops = {
-        .hash = dns_name_hash_func,
-        .compare = dns_name_compare_func
-};
+DEFINE_HASH_OPS(dns_name_hash_ops, char, dns_name_hash_func, dns_name_compare_func);
 
 int dns_name_equal(const char *x, const char *y) {
         int r, q;
@@ -534,11 +553,11 @@ int dns_name_equal(const char *x, const char *y) {
         for (;;) {
                 char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
 
-                r = dns_label_unescape(&x, la, sizeof(la));
+                r = dns_label_unescape(&x, la, sizeof la, 0);
                 if (r < 0)
                         return r;
 
-                q = dns_label_unescape(&y, lb, sizeof(lb));
+                q = dns_label_unescape(&y, lb, sizeof lb, 0);
                 if (q < 0)
                         return q;
 
@@ -565,14 +584,14 @@ int dns_name_endswith(const char *name, const char *suffix) {
         for (;;) {
                 char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
 
-                r = dns_label_unescape(&n, ln, sizeof(ln));
+                r = dns_label_unescape(&n, ln, sizeof ln, 0);
                 if (r < 0)
                         return r;
 
                 if (!saved_n)
                         saved_n = n;
 
-                q = dns_label_unescape(&s, ls, sizeof(ls));
+                q = dns_label_unescape(&s, ls, sizeof ls, 0);
                 if (q < 0)
                         return q;
 
@@ -603,13 +622,13 @@ int dns_name_startswith(const char *name, const char *prefix) {
         for (;;) {
                 char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
 
-                r = dns_label_unescape(&p, lp, sizeof(lp));
+                r = dns_label_unescape(&p, lp, sizeof lp, 0);
                 if (r < 0)
                         return r;
                 if (r == 0)
                         return true;
 
-                q = dns_label_unescape(&n, ln, sizeof(ln));
+                q = dns_label_unescape(&n, ln, sizeof ln, 0);
                 if (q < 0)
                         return q;
 
@@ -638,14 +657,14 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
                 if (!saved_before)
                         saved_before = n;
 
-                r = dns_label_unescape(&n, ln, sizeof(ln));
+                r = dns_label_unescape(&n, ln, sizeof ln, 0);
                 if (r < 0)
                         return r;
 
                 if (!saved_after)
                         saved_after = n;
 
-                q = dns_label_unescape(&s, ls, sizeof(ls));
+                q = dns_label_unescape(&s, ls, sizeof ls, 0);
                 if (q < 0)
                         return q;
 
@@ -668,7 +687,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
         /* Found it! Now generate the new name */
         prefix = strndupa(name, saved_before - name);
 
-        r = dns_name_concat(prefix, new_suffix, ret);
+        r = dns_name_concat(prefix, new_suffix, 0, ret);
         if (r < 0)
                 return r;
 
@@ -746,7 +765,7 @@ int dns_name_address(const char *p, int *family, union in_addr_union *address) {
                 for (i = 0; i < ELEMENTSOF(a); i++) {
                         char label[DNS_LABEL_MAX+1];
 
-                        r = dns_label_unescape(&p, label, sizeof(label));
+                        r = dns_label_unescape(&p, label, sizeof label, 0);
                         if (r < 0)
                                 return r;
                         if (r == 0)
@@ -783,7 +802,7 @@ int dns_name_address(const char *p, int *family, union in_addr_union *address) {
                         char label[DNS_LABEL_MAX+1];
                         int x, y;
 
-                        r = dns_label_unescape(&p, label, sizeof(label));
+                        r = dns_label_unescape(&p, label, sizeof label, 0);
                         if (r <= 0)
                                 return r;
                         if (r != 1)
@@ -792,7 +811,7 @@ int dns_name_address(const char *p, int *family, union in_addr_union *address) {
                         if (x < 0)
                                 return -EINVAL;
 
-                        r = dns_label_unescape(&p, label, sizeof(label));
+                        r = dns_label_unescape(&p, label, sizeof label, 0);
                         if (r <= 0)
                                 return r;
                         if (r != 1)
@@ -861,7 +880,7 @@ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, boo
                  * dns_label_unescape() returns 0 when it hits the end
                  * of the domain name, which we rely on here to encode
                  * the trailing NUL byte. */
-                r = dns_label_unescape(&domain, (char *) out, len);
+                r = dns_label_unescape(&domain, (char *) out, len, 0);
                 if (r < 0)
                         return r;
 
@@ -929,7 +948,7 @@ bool dns_srv_type_is_valid(const char *name) {
 
                 /* This more or less implements RFC 6335, Section 5.1 */
 
-                r = dns_label_unescape(&name, label, sizeof(label));
+                r = dns_label_unescape(&name, label, sizeof label, 0);
                 if (r < 0)
                         return false;
                 if (r == 0)
@@ -989,7 +1008,7 @@ int dns_service_join(const char *name, const char *type, const char *domain, cha
                 return -EINVAL;
 
         if (!name)
-                return dns_name_concat(type, domain, ret);
+                return dns_name_concat(type, domain, 0, ret);
 
         if (!dns_service_name_is_valid(name))
                 return -EINVAL;
@@ -998,11 +1017,11 @@ int dns_service_join(const char *name, const char *type, const char *domain, cha
         if (r < 0)
                 return r;
 
-        r = dns_name_concat(type, domain, &n);
+        r = dns_name_concat(type, domain, 0, &n);
         if (r < 0)
                 return r;
 
-        return dns_name_concat(escaped, n, ret);
+        return dns_name_concat(escaped, n, 0, ret);
 }
 
 static bool dns_service_name_label_is_valid(const char *label, size_t n) {
@@ -1027,7 +1046,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
         assert(joined);
 
         /* Get first label from the full name */
-        an = dns_label_unescape(&p, a, sizeof(a));
+        an = dns_label_unescape(&p, a, sizeof(a), 0);
         if (an < 0)
                 return an;
 
@@ -1035,7 +1054,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
                 x++;
 
                 /* If there was a first label, try to get the second one */
-                bn = dns_label_unescape(&p, b, sizeof(b));
+                bn = dns_label_unescape(&p, b, sizeof(b), 0);
                 if (bn < 0)
                         return bn;
 
@@ -1044,7 +1063,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
 
                         /* If there was a second label, try to get the third one */
                         q = p;
-                        cn = dns_label_unescape(&p, c, sizeof(c));
+                        cn = dns_label_unescape(&p, c, sizeof(c), 0);
                         if (cn < 0)
                                 return cn;
 
@@ -1094,7 +1113,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
         d = joined;
 
 finish:
-        r = dns_name_normalize(d, &domain);
+        r = dns_name_normalize(d, 0, &domain);
         if (r < 0)
                 return r;
 
@@ -1110,7 +1129,7 @@ finish:
         return 0;
 }
 
-static int dns_name_build_suffix_table(const char *name, const char*table[]) {
+static int dns_name_build_suffix_table(const char *name, const char *table[]) {
         const char *p;
         unsigned n = 0;
         int r;
@@ -1239,12 +1258,12 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
                 }
 
                 x = a_labels[n - 1 - k];
-                r = dns_label_unescape(&x, la, sizeof(la));
+                r = dns_label_unescape(&x, la, sizeof la, 0);
                 if (r < 0)
                         return r;
 
                 y = b_labels[m - 1 - k];
-                q = dns_label_unescape(&y, lb, sizeof(lb));
+                q = dns_label_unescape(&y, lb, sizeof lb, 0);
                 if (q < 0)
                         return q;
 
@@ -1295,7 +1314,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
 
         log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r));
         if (r == IDN2_2HYPHEN)
-                /* The name has two hypens — forbidden by IDNA2008 in some cases */
+                /* The name has two hyphens — forbidden by IDNA2008 in some cases */
                 return 0;
         if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
                 return -ENOSPC;
@@ -1312,13 +1331,13 @@ int dns_name_apply_idna(const char *name, char **ret) {
         for (;;) {
                 char label[DNS_LABEL_MAX];
 
-                r = dns_label_unescape(&name, label, sizeof(label));
+                r = dns_label_unescape(&name, label, sizeof label, 0);
                 if (r < 0)
                         return r;
                 if (r == 0)
                         break;
 
-                q = dns_label_apply_idna(label, r, label, sizeof(label));
+                q = dns_label_apply_idna(label, r, label, sizeof label);
                 if (q < 0)
                         return q;
                 if (q > 0)
diff --git a/src/systemd/src/shared/dns-domain.h b/src/systemd/src/shared/dns-domain.h
index 95f4069c..17db7c52 100644
--- a/src/systemd/src/shared/dns-domain.h
+++ b/src/systemd/src/shared/dns-domain.h
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
-#include <errno.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
@@ -24,13 +23,18 @@
 /* Maximum number of labels per valid hostname */
 #define DNS_N_LABELS_MAX 127
 
-int dns_label_unescape(const char **name, char *dest, size_t sz);
+typedef enum DNSLabelFlags {
+        DNS_LABEL_LDH        = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
+        DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
+} DNSLabelFlags;
+
+int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
 int dns_label_unescape_suffix(const char *name, const char **label_end, char *dest, size_t sz);
 int dns_label_escape(const char *p, size_t l, char *dest, size_t sz);
 int dns_label_escape_new(const char *p, size_t l, char **ret);
 
 static inline int dns_name_parent(const char **name) {
-        return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
+        return dns_label_unescape(name, NULL, DNS_LABEL_MAX, 0);
 }
 
 #if 0 /* NM_IGNORED */
@@ -40,18 +44,29 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
 #endif
 #endif /* NM_IGNORED */
 
-int dns_name_concat(const char *a, const char *b, char **ret);
+int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret);
 
-static inline int dns_name_normalize(const char *s, char **ret) {
+static inline int dns_name_normalize(const char *s, DNSLabelFlags flags, char **ret) {
         /* dns_name_concat() normalizes as a side-effect */
-        return dns_name_concat(s, NULL, ret);
+        return dns_name_concat(s, NULL, flags, ret);
 }
 
 static inline int dns_name_is_valid(const char *s) {
         int r;
 
         /* dns_name_normalize() verifies as a side effect */
-        r = dns_name_normalize(s, NULL);
+        r = dns_name_normalize(s, 0, NULL);
+        if (r == -EINVAL)
+                return 0;
+        if (r < 0)
+                return r;
+        return 1;
+}
+
+static inline int dns_name_is_valid_ldh(const char *s) {
+        int r;
+
+        r = dns_name_concat(s, NULL, DNS_LABEL_LDH|DNS_LABEL_NO_ESCAPES, NULL);
         if (r == -EINVAL)
                 return 0;
         if (r < 0)
@@ -59,8 +74,8 @@ static inline int dns_name_is_valid(const char *s) {
         return 1;
 }
 
-void dns_name_hash_func(const void *s, struct siphash *state);
-int dns_name_compare_func(const void *a, const void *b);
+void dns_name_hash_func(const char *s, struct siphash *state);
+int dns_name_compare_func(const char *a, const char *b);
 extern const struct hash_ops dns_name_hash_ops;
 
 int dns_name_between(const char *a, const char *b, const char *c);
diff --git a/src/systemd/src/systemd/_sd-common.h b/src/systemd/src/systemd/_sd-common.h
index 4742b2e7..b3ee7bbc 100644
--- a/src/systemd/src/systemd/_sd-common.h
+++ b/src/systemd/src/systemd/_sd-common.h
@@ -23,24 +23,26 @@
 #  error "Do not include _sd-common.h directly; it is a private header."
 #endif
 
+typedef void (*_sd_destroy_t)(void *userdata);
+
 #ifndef _sd_printf_
 #  if __GNUC__ >= 4
-#    define _sd_printf_(a,b) __attribute__ ((format (printf, a, b)))
+#    define _sd_printf_(a,b) __attribute__((__format__(printf, a, b)))
 #  else
 #    define _sd_printf_(a,b)
 #  endif
 #endif
 
 #ifndef _sd_sentinel_
-#  define _sd_sentinel_ __attribute__((sentinel))
+#  define _sd_sentinel_ __attribute__((__sentinel__))
 #endif
 
 #ifndef _sd_packed_
-#  define _sd_packed_ __attribute__((packed))
+#  define _sd_packed_ __attribute__((__packed__))
 #endif
 
 #ifndef _sd_pure_
-#  define _sd_pure_ __attribute__((pure))
+#  define _sd_pure_ __attribute__((__pure__))
 #endif
 
 #ifndef _SD_STRINGIFY
@@ -70,6 +72,14 @@
 #  endif
 #endif
 
+#ifndef _SD_ARRAY_STATIC
+#  if __STDC_VERSION__ >= 199901L
+#    define _SD_ARRAY_STATIC static
+#  else
+#    define _SD_ARRAY_STATIC
+#  endif
+#endif
+
 #define _SD_DEFINE_POINTER_CLEANUP_FUNC(type, func)             \
         static __inline__ void func##p(type **p) {              \
                 if (*p)                                         \
diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h
index e3885520..bd0d429d 100644
--- a/src/systemd/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/src/systemd/sd-dhcp-client.h
@@ -23,6 +23,7 @@
 #include <net/ethernet.h>
 #include <netinet/in.h>
 #include <sys/types.h>
+#include <stdbool.h>
 
 #include "sd-dhcp-lease.h"
 #include "sd-event.h"
@@ -127,12 +128,14 @@ int sd_dhcp_client_set_client_id(
                 size_t data_len);
 int sd_dhcp_client_set_iaid_duid(
                 sd_dhcp_client *client,
+                bool iaid_set,
                 uint32_t iaid,
                 uint16_t duid_type,
                 const void *duid,
                 size_t duid_len);
 int sd_dhcp_client_set_iaid_duid_llt(
                 sd_dhcp_client *client,
+                bool iaid_set,
                 uint32_t iaid,
                 uint64_t llt_time);
 int sd_dhcp_client_set_duid(
diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h
index 2a60145f..d299c791 100644
--- a/src/systemd/src/systemd/sd-dhcp-lease.h
+++ b/src/systemd/src/systemd/sd-dhcp-lease.h
@@ -39,7 +39,7 @@ int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
 int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2);
 int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
-int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
 int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
@@ -57,6 +57,7 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
 int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination);
 int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length);
 int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway);
+int sd_dhcp_route_get_option(sd_dhcp_route *route);
 
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_lease, sd_dhcp_lease_unref);
 
diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h
index fa36dca9..43d38f5c 100644
--- a/src/systemd/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/src/systemd/sd-dhcp6-client.h
@@ -21,7 +21,6 @@
 
 #include <inttypes.h>
 #include <net/ethernet.h>
-#include <stdbool.h>
 #include <sys/types.h>
 
 #include "sd-dhcp6-lease.h"
@@ -120,8 +119,15 @@ int sd_dhcp6_client_get_information_request(
 int sd_dhcp6_client_set_request_option(
                 sd_dhcp6_client *client,
                 uint16_t option);
+int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client,
+                                          int *delegation);
 int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client,
-                                          bool delegation);
+                                          int delegation);
+int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client,
+                                        int *request);
+int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client,
+                                        int request);
+int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id);
 
 int sd_dhcp6_client_get_lease(
                 sd_dhcp6_client *client,
diff --git a/src/systemd/src/systemd/sd-event.h b/src/systemd/src/systemd/sd-event.h
index eb35b834..787a12f2 100644
--- a/src/systemd/src/systemd/sd-event.h
+++ b/src/systemd/src/systemd/sd-event.h
@@ -33,7 +33,8 @@
   - Supports event source prioritization
   - Scales better with a large number of time events because it does not require one timerfd each
   - Automatically tries to coalesce timer events system-wide
-  - Handles signals and child PIDs
+  - Handles signals, child PIDs, inotify events
+  - Supports systemd-style automatic watchdog event generation
 */
 
 _SD_BEGIN_DECLARATIONS;
@@ -76,7 +77,7 @@ typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si,
 typedef void* sd_event_child_handler_t;
 #endif
 typedef int (*sd_event_inotify_handler_t)(sd_event_source *s, const struct inotify_event *event, void *userdata);
-typedef void (*sd_event_destroy_t)(void *userdata);
+typedef _sd_destroy_t sd_event_destroy_t;
 
 int sd_event_default(sd_event **e);
 
@@ -142,6 +143,8 @@ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid);
 int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret);
 int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback);
 int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret);
+int sd_event_source_get_floating(sd_event_source *s);
+int sd_event_source_set_floating(sd_event_source *s, int b);
 
 /* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);
diff --git a/src/systemd/src/systemd/sd-id128.h b/src/systemd/src/systemd/sd-id128.h
index 143a0ffb..bdf88ed5 100644
--- a/src/systemd/src/systemd/sd-id128.h
+++ b/src/systemd/src/systemd/sd-id128.h
@@ -35,24 +35,26 @@ union sd_id128 {
 
 #define SD_ID128_STRING_MAX 33
 
-char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]);
+char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]);
 int sd_id128_from_string(const char *s, sd_id128_t *ret);
 
 int sd_id128_randomize(sd_id128_t *ret);
 
 int sd_id128_get_machine(sd_id128_t *ret);
-int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret);
 int sd_id128_get_boot(sd_id128_t *ret);
 int sd_id128_get_invocation(sd_id128_t *ret);
 
-#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
-        ((const sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
-                                   0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }})
+int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret);
+int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret);
 
 #define SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
         { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
                      0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }}
 
+#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
+        ((const sd_id128_t) SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15))
+
+
 /* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16
  * times. It is hence not a good idea to call this macro with an
  * expensive function as parameter or an expression with side
@@ -108,7 +110,12 @@ _sd_pure_ static __inline__ int sd_id128_is_null(sd_id128_t a) {
         return a.qwords[0] == 0 && a.qwords[1] == 0;
 }
 
+_sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) {
+        return a.qwords[0] == UINT64_C(0xFFFFFFFFFFFFFFFF) && a.qwords[1] == UINT64_C(0xFFFFFFFFFFFFFFFF);
+}
+
 #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }})
+#define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }})
 
 _SD_END_DECLARATIONS;
 
diff --git a/src/systemd/src/systemd/sd-lldp.h b/src/systemd/src/systemd/sd-lldp.h
index d650794c..bf3afadc 100644
--- a/src/systemd/src/systemd/sd-lldp.h
+++ b/src/systemd/src/systemd/sd-lldp.h
@@ -27,7 +27,7 @@
 
 _SD_BEGIN_DECLARATIONS;
 
-/* IEEE 802.3AB Clause 9: TLV Types */
+/* IEEE 802.1AB-2009 Clause 8: TLV Types */
 enum {
         SD_LLDP_TYPE_END                 = 0,
         SD_LLDP_TYPE_CHASSIS_ID          = 1,
@@ -41,7 +41,7 @@ enum {
         SD_LLDP_TYPE_PRIVATE             = 127,
 };
 
-/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
+/* IEEE 802.1AB-2009 Clause 8.5.2: Chassis subtypes */
 enum {
         SD_LLDP_CHASSIS_SUBTYPE_RESERVED            = 0,
         SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT   = 1,
@@ -53,7 +53,7 @@ enum {
         SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED    = 7,
 };
 
-/* IEEE 802.3AB Clause 9.5.3: Port subtype */
+/* IEEE 802.1AB-2009 Clause 8.5.3: Port subtype */
 enum {
         SD_LLDP_PORT_SUBTYPE_RESERVED         = 0,
         SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS  = 1,
@@ -65,6 +65,7 @@ enum {
         SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
 };
 
+/* IEEE 802.1AB-2009 Clause 8.5.8: System capabilities */
 enum {
         SD_LLDP_SYSTEM_CAPABILITIES_OTHER    = 1 << 0,
         SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
@@ -95,6 +96,7 @@ enum {
 #define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
 #define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
 
+/* IEEE 802.1AB-2009 Annex E */
 enum {
         SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID          = 1,
         SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
@@ -105,14 +107,24 @@ enum {
         SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION      = 7,
 };
 
+/* IEEE 802.1AB-2009 Annex F */
+enum {
+        SD_LLDP_OUI_802_3_SUBTYPE_MAC_PHY_CONFIG_STATUS = 1,
+        SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI         = 2,
+        SD_LLDP_OUI_802_3_SUBTYPE_LINK_AGGREGATION      = 3,
+        SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE    = 4,
+};
+
 typedef struct sd_lldp sd_lldp;
 typedef struct sd_lldp_neighbor sd_lldp_neighbor;
 
 typedef enum sd_lldp_event {
-        SD_LLDP_EVENT_ADDED     = 'a',
-        SD_LLDP_EVENT_REMOVED   = 'r',
-        SD_LLDP_EVENT_UPDATED   = 'u',
-        SD_LLDP_EVENT_REFRESHED = 'f',
+        SD_LLDP_EVENT_ADDED,
+        SD_LLDP_EVENT_REMOVED,
+        SD_LLDP_EVENT_UPDATED,
+        SD_LLDP_EVENT_REFRESHED,
+        _SD_LLDP_EVENT_MAX,
+        _SD_LLDP_EVENT_INVALID = -1,
 } sd_lldp_event;
 
 typedef void (*sd_lldp_callback_t)(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata);
@@ -166,8 +178,8 @@ int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n);
 int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n);
 int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type);
 int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type);
-int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], uint8_t *subtype);
-int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[3], uint8_t subtype);
+int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t *subtype);
+int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t subtype);
 int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
 
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp, sd_lldp_unref);
diff --git a/src/systemd/src/systemd/sd-ndisc.h b/src/systemd/src/systemd/sd-ndisc.h
index 6b6249ca..d1bee343 100644
--- a/src/systemd/src/systemd/sd-ndisc.h
+++ b/src/systemd/src/systemd/sd-ndisc.h
@@ -55,8 +55,10 @@ typedef struct sd_ndisc sd_ndisc;
 typedef struct sd_ndisc_router sd_ndisc_router;
 
 typedef enum sd_ndisc_event {
-        SD_NDISC_EVENT_TIMEOUT = 't',
-        SD_NDISC_EVENT_ROUTER  = 'r',
+        SD_NDISC_EVENT_TIMEOUT,
+        SD_NDISC_EVENT_ROUTER,
+        _SD_NDISC_EVENT_MAX,
+        _SD_NDISC_EVENT_INVALID = -1,
 } sd_ndisc_event;
 
 typedef void (*sd_ndisc_callback_t)(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata);