diff --git a/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch b/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch
deleted file mode 100644
index f7b3a61..0000000
--- a/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch
+++ /dev/null
@@ -1,257 +0,0 @@
-From d4bd8777a483ea834e687c1ee35dee32efe6e49f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Wed, 7 Jul 2021 14:02:36 +0200
-Subject: [PATCH 1/5] rpm: don't specify the full path for systemctl and other
- commands
-
-We can make things a bit simpler and more readable by not specifying the path.
-Since we didn't specify the full path for all commands (including those invoked
-recursively by anythign we invoke), this didn't really privide any security or
-robustness benefits. I guess that full paths were used because this style of
-rpm packagnig was popular in the past, with macros used for everything
-possible, with special macros for common commands like %{__ln} and %{__mkdir}.
-
-(cherry picked from commit 7d9ee15d0fc2af87481ee371b278dbe7e68165ef)
----
- src/rpm/macros.systemd.in      | 24 ++++++++++++------------
- src/rpm/triggers.systemd.in    | 18 +++++++++---------
- src/rpm/triggers.systemd.sh.in | 18 +++++++++---------
- 3 files changed, 30 insertions(+), 30 deletions(-)
-
-diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
-index 3a0169a85f..3129ab2d61 100644
---- a/src/rpm/macros.systemd.in
-+++ b/src/rpm/macros.systemd.in
-@@ -46,9 +46,9 @@ OrderWithRequires(postun): systemd \
- 
- %systemd_post() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \
--if [ $1 -eq 1 ] && [ -x %{_bindir}/systemctl ]; then \
-+if [ $1 -eq 1 ] && command -v systemctl >/dev/null; then \
-     # Initial installation \
--    %{_bindir}/systemctl --no-reload preset %{?*} || : \
-+    systemctl --no-reload preset %{?*} || : \
- fi \
- %{nil}
- 
-@@ -56,21 +56,21 @@ fi \
- 
- %systemd_preun() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \
--if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \
-+if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
-     # Package removal, not upgrade \
-     if [ -d /run/systemd/system ]; then \
--          %{_bindir}/systemctl --no-reload disable --now %{?*} || : \
-+          systemctl --no-reload disable --now %{?*} || : \
-     else \
--          %{_bindir}/systemctl --no-reload disable %{?*} || : \
-+          systemctl --no-reload disable %{?*} || : \
-     fi \
- fi \
- %{nil}
- 
- %systemd_user_preun() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \
--if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \
-+if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
-     # Package removal, not upgrade \
--    %{_bindir}/systemctl --global disable %{?*} || : \
-+    systemctl --global disable %{?*} || : \
- fi \
- %{nil}
- 
-@@ -84,10 +84,10 @@ fi \
- 
- %systemd_postun_with_restart() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
--if [ $1 -ge 1 ] && [ -x %{_bindir}/systemctl ]; then \
-+if [ $1 -ge 1 ] && command -v systemctl >/dev/null; then \
-     # Package upgrade, not uninstall \
-     for unit in %{?*}; do \
--         %{_bindir}/systemctl set-property $unit Markers=+needs-restart || : \
-+        systemctl set-property $unit Markers=+needs-restart || : \
-     done \
- fi \
- %{nil}
-@@ -105,17 +105,17 @@ fi \
- # Deprecated. Use %tmpfiles_create_package instead
- %tmpfiles_create() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# tmpfiles_create}} \
--[ -x %{_bindir}/systemd-tmpfiles ] && %{_bindir}/systemd-tmpfiles --create %{?*} || : \
-+command -v systemd-tmpfiles >/dev/null && systemd-tmpfiles --create %{?*} || : \
- %{nil}
- 
- # Deprecated. Use %sysusers_create_package instead
- %sysusers_create() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# sysusers_create}} \
--[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers %{?*} || : \
-+command -v systemd-sysusers >/dev/null && systemd-sysusers %{?*} || : \
- %{nil}
- 
- %sysusers_create_inline() \
--[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \
-+command -v systemd-sysusers >/dev/null && systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \
- %{?*} \
- SYSTEMD_INLINE_EOF\
- %{nil}
-diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in
-index b33d2212e8..247358008a 100644
---- a/src/rpm/triggers.systemd.in
-+++ b/src/rpm/triggers.systemd.in
-@@ -16,14 +16,14 @@
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
-+        assert(posix.execp("systemctl", "daemon-reload"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
- 
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
-+        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -38,7 +38,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
-+        assert(posix.execp("systemctl", "daemon-reload"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -49,7 +49,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
-+        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -62,7 +62,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemd-sysusers"))
-+        assert(posix.execp("systemd-sysusers"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -74,7 +74,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemd-hwdb", "update"))
-+        assert(posix.execp("systemd-hwdb", "update"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -86,7 +86,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/journalctl", "--update-catalog"))
-+        assert(posix.execp("journalctl", "--update-catalog"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -111,7 +111,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/systemd-tmpfiles", "--create"))
-+        assert(posix.execp("systemd-tmpfiles", "--create"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-@@ -123,7 +123,7 @@ end
- if posix.access("/run/systemd/system") then
-     pid = posix.fork()
-     if pid == 0 then
--        assert(posix.exec("%{_bindir}/udevadm", "control", "--reload"))
-+        assert(posix.execp("udevadm", "control", "--reload"))
-     elseif pid > 0 then
-         posix.wait(pid)
-     end
-diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in
-index 22abad9812..1631be18c9 100644
---- a/src/rpm/triggers.systemd.sh.in
-+++ b/src/rpm/triggers.systemd.sh.in
-@@ -15,8 +15,8 @@
- # installed, because other cases are covered by the *un scriptlets,
- # so sometimes we will reload needlessly.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemctl daemon-reload || :
--  %{_bindir}/systemctl reload-or-restart --marked || :
-+  systemctl daemon-reload || :
-+  systemctl reload-or-restart --marked || :
- fi
- 
- %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
-@@ -26,13 +26,13 @@ fi
- # have been installed, but before %postun scripts in packages get
- # executed.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemctl daemon-reload || :
-+  systemctl daemon-reload || :
- fi
- 
- %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- # We restart remaining services that should be restarted here.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemctl reload-or-restart --marked || :
-+  systemctl reload-or-restart --marked || :
- fi
- 
- %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}}
-@@ -40,21 +40,21 @@ fi
- # specified users automatically. The priority is set such that it
- # will run before the tmpfiles file trigger.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemd-sysusers || :
-+  systemd-sysusers || :
- fi
- 
- %transfiletriggerin -P 1000700 udev -- {{UDEV_HWDB_DIR}}
- # This script will automatically invoke hwdb update if files have been
- # installed or updated in {{UDEV_HWDB_DIR}}.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemd-hwdb update || :
-+  systemd-hwdb update || :
- fi
- 
- %transfiletriggerin -P 1000700 -- {{SYSTEMD_CATALOG_DIR}}
- # This script will automatically invoke journal catalog update if files
- # have been installed or updated in {{SYSTEMD_CATALOG_DIR}}.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/journalctl --update-catalog || :
-+  journalctl --update-catalog || :
- fi
- 
- %transfiletriggerin -P 1000700 -- {{BINFMT_DIR}}
-@@ -71,14 +71,14 @@ fi
- # tmpfiles automatically. The priority is set such that it will run
- # after the sysusers file trigger, but before any other triggers.
- if test -d "/run/systemd/system"; then
--  %{_bindir}/systemd-tmpfiles --create || :
-+  systemd-tmpfiles --create || :
- fi
- 
- %transfiletriggerin -P 1000600 udev -- {{UDEV_RULES_DIR}}
- # This script will automatically update udev with new rules if files
- # have been installed or updated in {{UDEV_RULES_DIR}}.
- if test -e /run/udev/control; then
--  %{_bindir}/udevadm control --reload || :
-+  udevadm control --reload || :
- fi
- 
- %transfiletriggerin -P 1000500 -- {{SYSCTL_DIR}}
--- 
-2.31.1
-
diff --git a/0001-sysv-generator-downgrade-log-warning-about-autogener.patch b/0001-sysv-generator-downgrade-log-warning-about-autogener.patch
deleted file mode 100644
index df2bbee..0000000
--- a/0001-sysv-generator-downgrade-log-warning-about-autogener.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0c21535392bf6296d213c35fd1a0b0bc89dbddb3 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Wed, 31 Mar 2021 14:04:09 -0700
-Subject: [PATCH] sysv-generator: downgrade log warning about autogenerated to
- debug
-
----
- src/sysv-generator/sysv-generator.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
-index 8c7aef23c3..89599a69ee 100644
---- a/src/sysv-generator/sysv-generator.c
-+++ b/src/sysv-generator/sysv-generator.c
-@@ -786,9 +786,9 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
-                         if (!fpath)
-                                 return log_oom();
-
--                        log_warning("SysV service '%s' lacks a native systemd unit file. "
--                                    "Automatically generating a unit file for compatibility. "
--                                    "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath);
-+                        log_debug("SysV service '%s' lacks a native systemd unit file. "
-+                                  "Automatically generating a unit file for compatibility. "
-+                                  "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath);
-
-                         service = new(SysvStub, 1);
-                         if (!service)
---
-2.30.2
-
diff --git a/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch b/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch
deleted file mode 100644
index 32047c5..0000000
--- a/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch
+++ /dev/null
@@ -1,337 +0,0 @@
-From 09e8c6aa71ee4b5ff3ee85fc4855e2c1a246a079 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Thu, 22 Jul 2021 11:22:33 +0200
-Subject: [PATCH 2/5] rpm: use a helper script to actually invoke systemctl
- commands
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Instead of embedding the commands to invoke directly in the macros,
-let's use a helper script as indirection. This has a couple of advantages:
-
-- the macro language is awkward, we need to suffix most commands by "|| :"
-  and "\", which is easy to get wrong. In the new scheme, the macro becomes
-  a single simple command.
-- in the script we can use normal syntax highlighting, shellcheck, etc.
-- it's also easier to test the invoked commands by invoking the helper
-  manually.
-- most importantly, the logic is contained in the helper, i.e. we can
-  update systemd rpm and everything uses the new helper. Before, we would
-  have to rebuild all packages to update the macro definition.
-
-This raises the question whether it makes sense to use the lua scriptlets when
-the real work is done in a bash script. I think it's OK: we still have the
-efficient lua scripts that do the short scripts, and we use a single shared
-implementation in bash to do the more complex stuff.
-
-The meson version is raised to 0.47 because that's needed for install_mode.
-We were planning to raise the required version anyway…
-
-(cherry picked from commit 6d825ab2d42d3219e49a192bf99f9c09134a0df4)
----
- README                           |  2 +-
- meson.build                      |  3 +-
- src/rpm/macros.systemd.in        | 30 ++++++++--------
- src/rpm/meson.build              | 13 ++++---
- src/rpm/systemd-update-helper.in | 60 ++++++++++++++++++++++++++++++++
- src/rpm/triggers.systemd.in      | 43 ++++++++---------------
- src/rpm/triggers.systemd.sh.in   | 13 ++-----
- 7 files changed, 105 insertions(+), 59 deletions(-)
- create mode 100755 src/rpm/systemd-update-helper.in
-
-diff --git a/README b/README
-index 0e5c326deb..a8f23a0d5b 100644
---- a/README
-+++ b/README
-@@ -193,7 +193,7 @@ REQUIREMENTS:
-         python-jinja2
-         python-lxml (optional, required to build the indices)
-         python >= 3.5
--        meson >= 0.46 (>= 0.49 is required to build position-independent executables)
-+        meson >= 0.47 (>= 0.49 is required to build position-independent executables)
-         ninja
-         gcc, awk, sed, grep, and similar tools
-         clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs
-diff --git a/meson.build b/meson.build
-index 738879eb21..fb986e84f7 100644
---- a/meson.build
-+++ b/meson.build
-@@ -10,7 +10,7 @@ project('systemd', 'c',
-                 'localstatedir=/var',
-                 'warning_level=2',
-         ],
--        meson_version : '>= 0.46',
-+        meson_version : '>= 0.47',
-        )
- 
- libsystemd_version = '0.32.0'
-@@ -253,6 +253,7 @@ conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               join_paths(rootlib
- conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH',           join_paths(bindir, 'systemd-stdio-bridge'))
- conf.set_quoted('SYSTEMD_TEST_DATA',                          join_paths(testsdir, 'testdata'))
- conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
-+conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH',                 join_paths(rootlibexecdir, 'systemd-update-helper'))
- conf.set_quoted('SYSTEMD_USERWORK_PATH',                      join_paths(rootlibexecdir, 'systemd-userwork'))
- conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   join_paths(rootlibexecdir, 'systemd-veritysetup'))
- conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     join_paths(pkgsysconfdir, 'system'))
-diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
-index 3129ab2d61..bbdf036da7 100644
---- a/src/rpm/macros.systemd.in
-+++ b/src/rpm/macros.systemd.in
-@@ -46,31 +46,33 @@ OrderWithRequires(postun): systemd \
- 
- %systemd_post() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \
--if [ $1 -eq 1 ] && command -v systemctl >/dev/null; then \
-+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-     # Initial installation \
--    systemctl --no-reload preset %{?*} || : \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-system-units %{?*} || : \
- fi \
- %{nil}
- 
--%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
-+%systemd_user_post() \
-+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_post}} \
-+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-+    # Initial installation \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-user-units %{?*} || : \
-+fi \
-+%{nil}
- 
- %systemd_preun() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \
--if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
-+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-     # Package removal, not upgrade \
--    if [ -d /run/systemd/system ]; then \
--          systemctl --no-reload disable --now %{?*} || : \
--    else \
--          systemctl --no-reload disable %{?*} || : \
--    fi \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-system-units %{?*} || : \
- fi \
- %{nil}
- 
- %systemd_user_preun() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \
--if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
-+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-     # Package removal, not upgrade \
--    systemctl --global disable %{?*} || : \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \
- fi \
- %{nil}
- 
-@@ -84,11 +86,9 @@ fi \
- 
- %systemd_postun_with_restart() \
- %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
--if [ $1 -ge 1 ] && command -v systemctl >/dev/null; then \
-+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-     # Package upgrade, not uninstall \
--    for unit in %{?*}; do \
--        systemctl set-property $unit Markers=+needs-restart || : \
--    done \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \
- fi \
- %{nil}
- 
-diff --git a/src/rpm/meson.build b/src/rpm/meson.build
-index fc72fee73c..2ad3308cc1 100644
---- a/src/rpm/meson.build
-+++ b/src/rpm/meson.build
-@@ -1,9 +1,13 @@
- # SPDX-License-Identifier: LGPL-2.1-or-later
- 
- in_files = [
--        ['macros.systemd',      rpmmacrosdir != 'no'],
--        ['triggers.systemd',    false],
--        ['triggers.systemd.sh', false]]
-+        ['macros.systemd',        rpmmacrosdir != 'no', rpmmacrosdir],
-+
-+        # we conditionalize on rpmmacrosdir, but install into rootlibexecdir
-+        ['systemd-update-helper', rpmmacrosdir != 'no', rootlibexecdir, 'rwxr-xr-x'],
-+
-+        ['triggers.systemd',      false],
-+        ['triggers.systemd.sh',   false]]
- 
- # The last two don't get installed anywhere, one of them needs to included in
- # the rpm spec file definition instead.
-@@ -17,6 +21,7 @@ foreach tuple : in_files
-                 command : [meson_render_jinja2, config_h, '@INPUT@'],
-                 capture : true,
-                 install : tuple[1],
--                install_dir : rpmmacrosdir,
-+                install_dir : tuple.length() > 2 ? tuple[2] : '',
-+                install_mode : tuple.length() > 3 ? tuple[3] : false,
-                 build_by_default : true)
- endforeach
-diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
-new file mode 100755
-index 0000000000..9fa49fa131
---- /dev/null
-+++ b/src/rpm/systemd-update-helper.in
-@@ -0,0 +1,60 @@
-+#!/bin/bash
-+set -eu
-+set -o pipefail
-+
-+command="${1:?}"
-+shift
-+
-+command -v systemctl >/dev/null || exit 0
-+
-+case "$command" in
-+    install-system-units)
-+        systemctl --no-reload preset "$@"
-+        ;;
-+
-+    install-user-units)
-+        systemctl --no-reload preset --global "$@"
-+        ;;
-+
-+    remove-system-units)
-+        if [ -d /run/systemd/system ]; then
-+            systemctl --no-reload disable --now "$@"
-+        else
-+            systemctl --no-reload disable "$@"
-+        fi
-+        ;;
-+
-+    remove-user-units)
-+        systemctl --global disable "$@"
-+        ;;
-+
-+    mark-restart-system-units)
-+        [ -d /run/systemd/system ] || exit 0
-+
-+        for unit in "$@"; do
-+            systemctl set-property "$unit" Markers=+needs-restart || :
-+        done
-+        ;;
-+
-+    system-reload-restart|system-reload|system-restart)
-+        if [ -n "$*" ]; then
-+            echo "Unexpected arguments for '$command': $*"
-+            exit 2
-+        fi
-+
-+        [ -d /run/systemd/system ] || exit 0
-+
-+        if [[ "$command" =~ reload ]]; then
-+            systemctl daemon-reload
-+        fi
-+
-+        if [[ "$command" =~ restart ]]; then
-+            systemctl reload-or-restart --marked
-+        fi
-+        ;;
-+
-+    *)
-+        echo "Unknown verb '$command'"
-+        exit 3
-+        ;;
-+esac
-diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in
-index 247358008a..d29cc33dfd 100644
---- a/src/rpm/triggers.systemd.in
-+++ b/src/rpm/triggers.systemd.in
-@@ -13,20 +13,11 @@
- -- upgraded. We care about the case where a package is initially
- -- installed, because other cases are covered by the *un scriptlets,
- -- so sometimes we will reload needlessly.
--if posix.access("/run/systemd/system") then
--    pid = posix.fork()
--    if pid == 0 then
--        assert(posix.execp("systemctl", "daemon-reload"))
--    elseif pid > 0 then
--        posix.wait(pid)
--    end
--
--    pid = posix.fork()
--    if pid == 0 then
--        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
--    elseif pid > 0 then
--        posix.wait(pid)
--    end
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload-restart"))
-+elseif pid > 0 then
-+    posix.wait(pid)
- end
- 
- %transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
-@@ -35,24 +26,20 @@ end
- -- On upgrade, we need to run daemon-reload after any new unit files
- -- have been installed, but before %postun scripts in packages get
- -- executed.
--if posix.access("/run/systemd/system") then
--    pid = posix.fork()
--    if pid == 0 then
--        assert(posix.execp("systemctl", "daemon-reload"))
--    elseif pid > 0 then
--        posix.wait(pid)
--    end
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload"))
-+elseif pid > 0 then
-+    posix.wait(pid)
- end
- 
- %transfiletriggerpostun -P 10000 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- -- We restart remaining services that should be restarted here.
--if posix.access("/run/systemd/system") then
--    pid = posix.fork()
--    if pid == 0 then
--        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
--    elseif pid > 0 then
--        posix.wait(pid)
--    end
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart"))
-+elseif pid > 0 then
-+    posix.wait(pid)
- end
- 
- %transfiletriggerin -P 100700 -p <lua> -- {{SYSUSERS_DIR}}
-diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in
-index 1631be18c9..83cd7617f8 100644
---- a/src/rpm/triggers.systemd.sh.in
-+++ b/src/rpm/triggers.systemd.sh.in
-@@ -14,10 +14,7 @@
- # upgraded. We care about the case where a package is initially
- # installed, because other cases are covered by the *un scriptlets,
- # so sometimes we will reload needlessly.
--if test -d "/run/systemd/system"; then
--  systemctl daemon-reload || :
--  systemctl reload-or-restart --marked || :
--fi
-+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || :
- 
- %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- # On removal, we need to run daemon-reload after any units have been
-@@ -25,15 +22,11 @@ fi
- # On upgrade, we need to run daemon-reload after any new unit files
- # have been installed, but before %postun scripts in packages get
- # executed.
--if test -d "/run/systemd/system"; then
--  systemctl daemon-reload || :
--fi
-+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || :
- 
- %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- # We restart remaining services that should be restarted here.
--if test -d "/run/systemd/system"; then
--  systemctl reload-or-restart --marked || :
--fi
-+{{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || :
- 
- %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}}
- # This script will process files installed in {{SYSUSERS_DIR}} to create
--- 
-2.31.1
-
diff --git a/0003-rpm-call-needs-restart-in-parallel.patch b/0003-rpm-call-needs-restart-in-parallel.patch
deleted file mode 100644
index 4637f3e..0000000
--- a/0003-rpm-call-needs-restart-in-parallel.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0a2e691b6b1fdceb4b7504870c4b792a66b5080f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Thu, 22 Jul 2021 11:28:36 +0200
-Subject: [PATCH 3/5] rpm: call +needs-restart in parallel
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some rpms install a bunch of units… It seems nicer to invoke them all in
-parallel. In particular, timeouts in systemctl also run in parallel, so if
-there's some communication mishap, we will wait less.
-
-(cherry picked from commit 3598aff4d963b2e51ac74d206161da47bfde785c)
----
- src/rpm/systemd-update-helper.in | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
-index 9fa49fa131..f3c75b75fa 100755
---- a/src/rpm/systemd-update-helper.in
-+++ b/src/rpm/systemd-update-helper.in
-@@ -32,8 +32,9 @@ case "$command" in
-         [ -d /run/systemd/system ] || exit 0
- 
-         for unit in "$@"; do
--            systemctl set-property "$unit" Markers=+needs-restart || :
-+            systemctl set-property "$unit" Markers=+needs-restart &
-         done
-+        wait
-         ;;
- 
-     system-reload-restart|system-reload|system-restart)
--- 
-2.31.1
-
diff --git a/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch b/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch
deleted file mode 100644
index eac9b89..0000000
--- a/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch
+++ /dev/null
@@ -1,259 +0,0 @@
-From a63d5d320f81c1cbae07897a401ed5cc5374e0bf Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Wed, 7 Jul 2021 14:37:57 +0200
-Subject: [PATCH 4/5] rpm: restart user services at the end of the transaction
-
-This closes an important gap: so far we would reexecute the system manager and
-restart system services that were configured to do so, but we wouldn't do the
-same for user managers or user services.
-
-The scheme used for user managers is very similar to the system one, except
-that there can be multiple user managers running, so we query the system
-manager to get a list of them, and then tell each one to do the equivalent
-operations: daemon-reload, disable --now, set-property Markers=+needs-restart,
-reload-or-restart --marked.
-
-The total time that can be spend on this is bounded: we execute the commands in
-parallel over user managers and units, and additionally set SYSTEMD_BUS_TIMEOUT
-to a lower value (15 s by default). User managers should not have too many
-units running, and they should be able to do all those operations very
-quickly (<< 1s). The final restart operation may take longer, but it's done
-asynchronously, so we only wait for the queuing to happen.
-
-The advantage of doing this synchronously is that we can wait for each step to
-happen, and for example daemon-reloads can finish before we execute the service
-restarts, etc. We can also order various steps wrt. to the phases in the rpm
-transaction.
-
-When this was initially proposed, we discussed a more relaxed scheme with bus
-property notifications. Such an approach would be more complex because a bunch
-of infrastructure would have to be added to system manager to propagate
-appropriate notifications to the user managers, and then the user managers
-would have to wait for them. Instead, now there is no new code in the managers,
-all new functionality is contained in src/rpm/. The ability to call 'systemctl
---user user@' makes this approach very easy. Also, it would be very hard to
-order the user manager steps and the rpm transaction steps.
-
-Note: 'systemctl --user disable' is only called for a user managers that are
-running. I don't see a nice way around this, and it shouldn't matter too much:
-we'll just leave a dangling symlink in the case where the user enabled the
-service manually.
-
-A follow-up for https://bugzilla.redhat.com/show_bug.cgi?id=1792468 and
-fa97d2fcf64e0558054bee673f734f523373b146.
-
-(cherry picked from commit 36d55958ccc75fa3c91bdd7354d74c910f2f6cc7)
----
- meson.build                      |  1 +
- meson_options.txt                |  2 ++
- src/rpm/macros.systemd.in        |  6 +++-
- src/rpm/systemd-update-helper.in | 47 ++++++++++++++++++++++++++++++++
- src/rpm/triggers.systemd.in      | 28 ++++++++++++++++++-
- src/rpm/triggers.systemd.sh.in   | 13 ++++++++-
- 6 files changed, 94 insertions(+), 3 deletions(-)
-
-diff --git a/meson.build b/meson.build
-index fb986e84f7..d898d9ccd0 100644
---- a/meson.build
-+++ b/meson.build
-@@ -270,6 +270,7 @@ conf.set_quoted('TMPFILES_DIR',                               tmpfilesdir)
- conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
- conf.set_quoted('UDEV_HWDB_DIR',                              udevhwdbdir)
- conf.set_quoted('UDEV_RULES_DIR',                             udevrulesdir)
-+conf.set_quoted('UPDATE_HELPER_USER_TIMEOUT',                 get_option('update-helper-user-timeout'))
- conf.set_quoted('USER_CONFIG_UNIT_DIR',                       join_paths(pkgsysconfdir, 'user'))
- conf.set_quoted('USER_DATA_UNIT_DIR',                         userunitdir)
- conf.set_quoted('USER_ENV_GENERATOR_DIR',                     userenvgeneratordir)
-diff --git a/meson_options.txt b/meson_options.txt
-index 163c8df87d..9383c7da6a 100644
---- a/meson_options.txt
-+++ b/meson_options.txt
-@@ -182,6 +182,8 @@ option('xinitrcdir', type : 'string', value : '',
-        description : 'directory for xinitrc files')
- option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d',
-        description : 'directory for rpm macros ["no" disables]')
-+option('update-helper-user-timeout', type : 'string', value : '15s',
-+       description : 'how long to wait for user manager operations')
- option('pamlibdir', type : 'string',
-        description : 'directory for PAM modules')
- option('pamconfdir', type : 'string',
-diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
-index bbdf036da7..caa2e45595 100644
---- a/src/rpm/macros.systemd.in
-+++ b/src/rpm/macros.systemd.in
-@@ -93,7 +93,11 @@ fi \
- %{nil}
- 
- %systemd_user_postun_with_restart() \
--%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
-+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun_with_restart}} \
-+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
-+    # Package upgrade, not uninstall \
-+    {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-user-units %{?*} || : \
-+fi \
- %{nil}
- 
- %udev_hwdb_update() %{nil}
-diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
-index f3c75b75fa..f3466ab3c0 100755
---- a/src/rpm/systemd-update-helper.in
-+++ b/src/rpm/systemd-update-helper.in
-@@ -26,6 +26,15 @@ case "$command" in
- 
-     remove-user-units)
-         systemctl --global disable "$@"
-+
-+        [ -d /run/systemd/system ] || exit 0
-+
-+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
-+        for user in $users; do
-+            SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
-+                    systemctl --user -M "$user@" disable --now "$@" &
-+        done
-+        wait
-         ;;
- 
-     mark-restart-system-units)
-@@ -37,6 +46,17 @@ case "$command" in
-         wait
-         ;;
- 
-+    mark-restart-user-units)
-+        [ -d /run/systemd/system ] || exit 0
-+
-+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
-+        for user in $users; do
-+            SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
-+                    systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart &
-+        done
-+        wait
-+        ;;
-+
-     system-reload-restart|system-reload|system-restart)
-         if [ -n "$*" ]; then
-             echo "Unexpected arguments for '$command': $*"
-@@ -54,6 +74,33 @@ case "$command" in
-         fi
-         ;;
- 
-+    user-reload-restart|user-reload|user-restart)
-+        if [ -n "$*" ]; then
-+            echo "Unexpected arguments for '$command': $*"
-+            exit 2
-+        fi
-+
-+        [ -d /run/systemd/system ] || exit 0
-+
-+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
-+
-+        if [[ "$command" =~ reload ]]; then
-+            for user in $users; do
-+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
-+                        systemctl --user -M "$user@" daemon-reload &
-+            done
-+            wait
-+        fi
-+
-+        if [[ "$command" =~ restart ]]; then
-+            for user in $users; do
-+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
-+                        systemctl --user -M "$user@" reload-or-restart --marked &
-+            done
-+            wait
-+        fi
-+        ;;
-+
-     *)
-         echo "Unknown verb '$command'"
-         exit 3
-diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in
-index d29cc33dfd..8aeb2049c1 100644
---- a/src/rpm/triggers.systemd.in
-+++ b/src/rpm/triggers.systemd.in
-@@ -20,6 +20,14 @@ elseif pid > 0 then
-     posix.wait(pid)
- end
- 
-+%transfiletriggerin -P 900899 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload-restart"))
-+elseif pid > 0 then
-+    posix.wait(pid)
-+end
-+
- %transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- -- On removal, we need to run daemon-reload after any units have been
- -- removed.
-@@ -33,8 +41,17 @@ elseif pid > 0 then
-     posix.wait(pid)
- end
- 
-+%transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
-+-- Execute daemon-reload in user managers.
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload"))
-+elseif pid > 0 then
-+    posix.wait(pid)
-+end
-+
- %transfiletriggerpostun -P 10000 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
---- We restart remaining services that should be restarted here.
-+-- We restart remaining system services that should be restarted here.
- pid = posix.fork()
- if pid == 0 then
-     assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart"))
-@@ -42,6 +59,15 @@ elseif pid > 0 then
-     posix.wait(pid)
- end
- 
-+%transfiletriggerpostun -P 9999 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
-+-- We restart remaining user services that should be restarted here.
-+pid = posix.fork()
-+if pid == 0 then
-+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-restart"))
-+elseif pid > 0 then
-+    posix.wait(pid)
-+end
-+
- %transfiletriggerin -P 100700 -p <lua> -- {{SYSUSERS_DIR}}
- -- This script will process files installed in {{SYSUSERS_DIR}} to create
- -- specified users automatically. The priority is set such that it
-diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in
-index 83cd7617f8..694cd94e8d 100644
---- a/src/rpm/triggers.systemd.sh.in
-+++ b/src/rpm/triggers.systemd.sh.in
-@@ -16,6 +16,9 @@
- # so sometimes we will reload needlessly.
- {{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || :
- 
-+%transfiletriggerin -P 900899 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
-+{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload-restart || :
-+
- %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
- # On removal, we need to run daemon-reload after any units have been
- # removed.
-@@ -24,10 +27,18 @@
- # executed.
- {{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || :
- 
-+%transfiletriggerpostun -P 1000099 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
-+# Execute daemon-reload in user managers.
-+{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload || :
-+
- %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
--# We restart remaining services that should be restarted here.
-+# We restart remaining system services that should be restarted here.
- {{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || :
- 
-+%transfiletriggerpostun -P  9999 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
-+# We restart remaining user services that should be restarted here.
-+{{SYSTEMD_UPDATE_HELPER_PATH}} user-restart || :
-+
- %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}}
- # This script will process files installed in {{SYSUSERS_DIR}} to create
- # specified users automatically. The priority is set such that it
--- 
-2.31.1
-
diff --git a/0005-update-helper-also-add-user-reexec-verb.patch b/0005-update-helper-also-add-user-reexec-verb.patch
deleted file mode 100644
index 7c4f7ba..0000000
--- a/0005-update-helper-also-add-user-reexec-verb.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 37cd6c0fad847e5fffd9d107358a36e767c7ca42 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Fri, 23 Jul 2021 15:35:23 +0200
-Subject: [PATCH 5/5] update-helper: also add "user-reexec" verb
-
-This is not called from the systemd.triggers or systemd.macros files. Instead,
-it would be called from the scriptlets in systemd rpm package itself, at the
-place where we call systemctl daemon-reexec.
-
-See https://github.com/systemd/systemd/pull/20289#issuecomment-885622200 .
-
-(cherry picked from commit 1262e824a4d638e347ae0d39c973f1f750962533)
----
- src/rpm/systemd-update-helper.in | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
-index f3466ab3c0..0c6675a9db 100755
---- a/src/rpm/systemd-update-helper.in
-+++ b/src/rpm/systemd-update-helper.in
-@@ -74,7 +74,7 @@ case "$command" in
-         fi
-         ;;
- 
--    user-reload-restart|user-reload|user-restart)
-+    user-reload-restart|user-reload|user-restart|user-reexec)
-         if [ -n "$*" ]; then
-             echo "Unexpected arguments for '$command': $*"
-             exit 2
-@@ -84,6 +84,14 @@ case "$command" in
- 
-         users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
- 
-+        if [[ "$command" =~ reexec ]]; then
-+            for user in $users; do
-+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
-+                        systemctl --user -M "$user@" daemon-reexec &
-+            done
-+            wait
-+        fi
-+
-         if [[ "$command" =~ reload ]]; then
-             for user in $users; do
-                 SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
--- 
-2.31.1
-
diff --git a/18621-fb.patch b/18621-fb.patch
deleted file mode 100644
index 9bd802a..0000000
--- a/18621-fb.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 0762f129c6a9c7bbdb5d575c486d5cf4f7fdae8d Mon Sep 17 00:00:00 2001
-From: Richard Purdie <richard.purdie@linuxfoundation.org>
-Date: Tue, 16 Feb 2021 12:17:36 +0000
-Subject: [PATCH] proc: dont trigger mount error with invalid options on old
- kernels
-
-As of commit 4e39995371738b04d98d27b0d34ea8fe09ec9fab ("core: introduce
-ProtectProc= and ProcSubset= to expose hidepid= and subset= procfs
-mount options") kernels older than v5.8 generate multple warnings at
-boot, as seen in this Yocto build from today:
-
-     qemux86-64 login: root
-     [   65.829009] proc: Bad value for 'hidepid'
-     root@qemux86-64:~# dmesg|grep proc:
-     [   16.990706] proc: Bad value for 'hidepid'
-     [   28.060178] proc: Bad value for 'hidepid'
-     [   28.874229] proc: Bad value for 'hidepid'
-     [   32.685107] proc: Bad value for 'hidepid'
-     [   65.829009] proc: Bad value for 'hidepid'
-     root@qemux86-64:~#
-
-We see reports of the issue as in general its hard to someone to tell
-the difference between an error in dmesg which they should worry about and
-one that is harmless. This adds support burden to developers so Yocto
-Project has added this patch.
-
-The commit that triggers this is systemd v247-rc1~378^2~3 -- so any
-systemd 247 and above plus kernel v5.7 or older will need this.
-
-As noted in https://github.com/systemd/systemd/issues/16896
-it is possible changes could be backported to different kernel versions
-so the test isn't 100% foolproof but does give better results than a
-continual stream of bug reports.
-
-Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-
-Changes from Anita Zhang <the.anitazha@gmail.com>
-- Use 5.6.13-0_fbk9 version comparison for FB build
----
- src/core/namespace.c | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
-
-diff --git a/src/core/namespace.c b/src/core/namespace.c
-index d47531408b..8be8352a8e 100644
---- a/src/core/namespace.c
-+++ b/src/core/namespace.c
-@@ -4,7 +4,9 @@
- #include <linux/loop.h>
- #include <sched.h>
- #include <stdio.h>
-+#include <stdlib.h>
- #include <sys/mount.h>
-+#include <sys/utsname.h>
- #include <unistd.h>
- #include <linux/fs.h>
- 
-@@ -1018,12 +1020,28 @@ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
-         _cleanup_free_ char *opts = NULL;
-         const char *entry_path;
-         int r, n;
-+        struct utsname uts;
-+        bool old = false;
- 
-         assert(m);
-         assert(ns_info);
- 
--        if (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
--            ns_info->proc_subset != PROC_SUBSET_ALL) {
-+        /* If uname says that the system is older than v5.6.13-0_fbk9, then the textual hidepid= stuff is not
-+         * supported by the kernel, and thus the per-instance hidepid= neither, which means we
-+         * really don't want to use it, since it would affect our host's /proc * mount. Hence let's
-+         * gracefully fallback to a classic, unrestricted version. */
-+
-+        r = uname(&uts);
-+        if (r < 0)
-+               return -errno;
-+
-+        if (strverscmp(uts.release, "5.6.13-0_fbk9") < 0) {
-+                log_debug("Pre v5.6.13-0_fbk9 kernel detected [v%s] - skipping hidepid=", uts.release);
-+                old = true;
-+        }
-+
-+        if (!old && (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
-+            ns_info->proc_subset != PROC_SUBSET_ALL)) {
- 
-                 /* Starting with kernel 5.8 procfs' hidepid= logic is truly per-instance (previously it
-                  * pretended to be per-instance but actually was per-namespace), hence let's make use of it
--- 
-2.30.2
-
diff --git a/18621.patch b/18621.patch
deleted file mode 100644
index 80bd969..0000000
--- a/18621.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From c225bc59b8907de11f389bd8efb82155ccde75a7 Mon Sep 17 00:00:00 2001
-From: Richard Purdie <richard.purdie@linuxfoundation.org>
-Date: Tue, 16 Feb 2021 12:17:36 +0000
-Subject: [PATCH] proc: dont trigger mount error with invalid options on old
- kernels
-
-As of commit 4e39995371738b04d98d27b0d34ea8fe09ec9fab ("core: introduce
-ProtectProc= and ProcSubset= to expose hidepid= and subset= procfs
-mount options") kernels older than v5.8 generate multple warnings at
-boot, as seen in this Yocto build from today:
-
-     qemux86-64 login: root
-     [   65.829009] proc: Bad value for 'hidepid'
-     root@qemux86-64:~# dmesg|grep proc:
-     [   16.990706] proc: Bad value for 'hidepid'
-     [   28.060178] proc: Bad value for 'hidepid'
-     [   28.874229] proc: Bad value for 'hidepid'
-     [   32.685107] proc: Bad value for 'hidepid'
-     [   65.829009] proc: Bad value for 'hidepid'
-     root@qemux86-64:~#
-
-We see reports of the issue as in general its hard to someone to tell
-the difference between an error in dmesg which they should worry about and
-one that is harmless. This adds support burden to developers so Yocto
-Project has added this patch.
-
-The commit that triggers this is systemd v247-rc1~378^2~3 -- so any
-systemd 247 and above plus kernel v5.7 or older will need this.
-
-As noted in https://github.com/systemd/systemd/issues/16896
-it is possible changes could be backported to different kernel versions
-so the test isn't 100% foolproof but does give better results than a
-continual stream of bug reports.
-
-Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
----
- src/core/namespace.c | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
-
-diff --git a/src/core/namespace.c b/src/core/namespace.c
-index 4ed0991b56d1..3fa2d4e9d640 100644
---- a/src/core/namespace.c
-+++ b/src/core/namespace.c
-@@ -4,7 +4,9 @@
- #include <linux/loop.h>
- #include <sched.h>
- #include <stdio.h>
-+#include <stdlib.h>
- #include <sys/mount.h>
-+#include <sys/utsname.h>
- #include <unistd.h>
- #include <linux/fs.h>
- 
-@@ -881,12 +883,28 @@ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
-         _cleanup_free_ char *opts = NULL;
-         const char *entry_path;
-         int r, n;
-+        struct utsname uts;
-+        bool old = false;
- 
-         assert(m);
-         assert(ns_info);
- 
--        if (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
--            ns_info->proc_subset != PROC_SUBSET_ALL) {
-+        /* If uname says that the system is older than v5.8, then the textual hidepid= stuff is not
-+         * supported by the kernel, and thus the per-instance hidepid= neither, which means we
-+         * really don't want to use it, since it would affect our host's /proc * mount. Hence let's
-+         * gracefully fallback to a classic, unrestricted version. */
-+
-+        r = uname(&uts);
-+        if (r < 0)
-+               return -errno;
-+
-+        if (strverscmp(uts.release, "5.8") < 0) {
-+                log_debug("Pre v5.8 kernel detected [v%s] - skipping hidepid=", uts.release);
-+                old = true;
-+        }
-+
-+        if (!old && (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
-+            ns_info->proc_subset != PROC_SUBSET_ALL)) {
- 
-                 /* Starting with kernel 5.8 procfs' hidepid= logic is truly per-instance (previously it
-                  * pretended to be per-instance but actually was per-namespace), hence let's make use of it
diff --git a/20-grubby.install b/20-grubby.install
deleted file mode 100755
index e059125..0000000
--- a/20-grubby.install
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-
-if [[ ! -x /sbin/new-kernel-pkg ]]; then
-    exit 0
-fi
-
-COMMAND="$1"
-KERNEL_VERSION="$2"
-BOOT_DIR_ABS="$3"
-KERNEL_IMAGE="$4"
-
-KERNEL_DIR="${KERNEL_IMAGE%/*}"
-[[ "$KERNEL_VERSION" == *\+* ]] && flavor=-"${KERNEL_VERSION##*+}"
-case "$COMMAND" in
-    add)
-        if [[ "${KERNEL_DIR}" != "/boot" ]]; then
-            for i in \
-                "$KERNEL_IMAGE" \
-                    "$KERNEL_DIR"/System.map \
-                    "$KERNEL_DIR"/config \
-                    "$KERNEL_DIR"/zImage.stub \
-                    "$KERNEL_DIR"/dtb \
-                ; do
-                [[ -e "$i" ]] || continue
-                cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}"
-                command -v restorecon &>/dev/null && \
-                    restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}"
-            done
-            # hmac is .vmlinuz-<version>.hmac so needs a special treatment
-            i="$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac"
-            if [[ -e "$i" ]]; then
-                cp -a "$i" "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac"
-                command -v restorecon &>/dev/null && \
-                    restorecon "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac"
-            fi
-        fi
-        /sbin/new-kernel-pkg --package "kernel${flavor}" --install "$KERNEL_VERSION" || exit $?
-        /sbin/new-kernel-pkg --package "kernel${flavor}" --mkinitrd --dracut --depmod --update "$KERNEL_VERSION" || exit $?
-        /sbin/new-kernel-pkg --package "kernel${flavor}" --rpmposttrans "$KERNEL_VERSION" || exit $?
-        ;;
-    remove)
-        /sbin/new-kernel-pkg --package "kernel${flavor+-$flavor}" --rminitrd --rmmoddep --remove "$KERNEL_VERSION" || exit $?
-        ;;
-    *)
-        ;;
-esac
-
-# skip other installation plugins, if we can't find a boot loader spec conforming setup
-if ! [[ -d /boot/loader/entries || -L /boot/loader/entries ]]; then
-    exit 77
-fi
diff --git a/20450.patch b/20450.patch
deleted file mode 100644
index e63c3d2..0000000
--- a/20450.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 0db68800c756f298ef45584ac01915c2cb2ce359 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Mon, 16 Aug 2021 23:47:40 +0900
-Subject: [PATCH 1/2] ethtool: make the size of 'features' array static
-
----
- src/shared/ethtool-util.c | 2 +-
- src/shared/ethtool-util.h | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index f77f6943ca4f..699c7a97ab97 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -501,7 +501,7 @@ static int set_features_bit(
-         return found ? 0 : -ENODATA;
- }
- 
--int ethtool_set_features(int *ethtool_fd, const char *ifname, const int *features) {
-+int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features[static _NET_DEV_FEAT_MAX]) {
-         _cleanup_free_ struct ethtool_gstrings *strings = NULL;
-         struct ethtool_sfeatures *sfeatures;
-         struct ifreq ifr = {};
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index 7d287666249a..f0fc40b0595f 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -88,7 +88,7 @@ int ethtool_get_link_info(int *ethtool_fd, const char *ifname,
- int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct ether_addr *ret);
- int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts);
- int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netdev_ring_param *ring);
--int ethtool_set_features(int *ethtool_fd, const char *ifname, const int *features);
-+int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features[static _NET_DEV_FEAT_MAX]);
- int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname,
-                               int autonegotiation, const uint32_t advertise[static N_ADVERTISE],
-                               uint64_t speed, Duplex duplex, NetDevPort port);
-
-From c2f2250e5c52ec3745a462e3f55a94c133786df8 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Tue, 17 Aug 2021 00:44:00 +0900
-Subject: [PATCH 2/2] ethtool: make ethtool_set_features() return earlier when
- nothing is requested
-
----
- src/shared/ethtool-util.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index 699c7a97ab97..4ca90615f3c1 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -505,12 +505,22 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
-         _cleanup_free_ struct ethtool_gstrings *strings = NULL;
-         struct ethtool_sfeatures *sfeatures;
-         struct ifreq ifr = {};
--        int i, r;
-+        bool have = false;
-+        int r;
- 
-         assert(ethtool_fd);
-         assert(ifname);
-         assert(features);
- 
-+        for (size_t i = 0; i < _NET_DEV_FEAT_MAX; i++)
-+                if (features[i] >= 0) {
-+                        have = true;
-+                        break;
-+                }
-+
-+        if (!have)
-+                return 0;
-+
-         r = ethtool_connect(ethtool_fd);
-         if (r < 0)
-                 return r;
-@@ -525,8 +535,8 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
-         sfeatures->cmd = ETHTOOL_SFEATURES;
-         sfeatures->size = DIV_ROUND_UP(strings->len, 32U);
- 
--        for (i = 0; i < _NET_DEV_FEAT_MAX; i++)
--                if (features[i] != -1) {
-+        for (size_t i = 0; i < _NET_DEV_FEAT_MAX; i++)
-+                if (features[i] >= 0) {
-                         r = set_features_bit(strings, netdev_feature_table[i], features[i], sfeatures);
-                         if (r < 0) {
-                                 log_debug_errno(r, "ethtool: could not find feature, ignoring: %s", netdev_feature_table[i]);
diff --git a/20458.patch b/20458.patch
deleted file mode 100644
index ad916b4..0000000
--- a/20458.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From e9f92c88163841d3f1d29fa5b44ae4c6f71bb014 Mon Sep 17 00:00:00 2001
-From: Daan De Meyer <daan.j.demeyer@gmail.com>
-Date: Wed, 18 Aug 2021 07:59:13 +0100
-Subject: [PATCH] udev: Support "max" string for BufferSize options (#20458)
-
-"max" indicates the hardware advertised maximum queue buffer size
-should be used.
-
-The max sizes can be checked by running `ethtool -g <dev>` (Preset maximums).
-Since the buffer sizes can't be set to 0 by users, internally we use 0 to
-indicate that the hardware advertised maximum should be used.
----
- man/systemd.link.xml      | 20 ++++++++++++--------
- src/shared/ethtool-util.c | 40 +++++++++++++++++++++++++--------------
- src/shared/ethtool-util.h |  2 ++
- 3 files changed, 40 insertions(+), 22 deletions(-)
-
-diff --git a/man/systemd.link.xml b/man/systemd.link.xml
-index 1c18f35fc8..fd744ebaed 100644
---- a/man/systemd.link.xml
-+++ b/man/systemd.link.xml
-@@ -735,29 +735,33 @@
-       <varlistentry>
-         <term><varname>RxBufferSize=</varname></term>
-         <listitem>
--          <para>Takes an integer. Specifies the maximum number of pending packets in the NIC receive buffer.
--          When unset, the kernel's default will be used.</para>
-+          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
-+          in the NIC receive buffer. When unset, the kernel's default will be used. If set to
-+          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-         <term><varname>RxMiniBufferSize=</varname></term>
-         <listitem>
--          <para>Takes an integer. Specifies the maximum number of pending packets in the NIC mini receive buffer.
--          When unset, the kernel's default will be used.</para>
-+          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
-+          in the NIC mini receive buffer. When unset, the kernel's default will be used. If set to
-+          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-         <term><varname>RxJumboBufferSize=</varname></term>
-         <listitem>
--          <para>Takes an integer. Specifies the maximum number of pending packets in the NIC jumbo receive buffer.
--          When unset, the kernel's default will be used.</para>
-+          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
-+          in the NIC jumbo receive buffer. When unset, the kernel's default will be used. If set to
-+          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-         <term><varname>TxBufferSize=</varname></term>
-         <listitem>
--          <para>Takes an integer. Specifies the maximum number of pending packets in the NIC transmit buffer.
--          When unset, the kernel's default will be used.</para>
-+          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
-+          in the NIC transmit buffer. When unset, the kernel's default will be used. If set to
-+          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index f77f6943ca..ed251ec8dd 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -399,16 +399,24 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-                 return -errno;
- 
-         if (ring->rx_pending_set)
--                UPDATE(ecmd.rx_pending, ring->rx_pending, need_update);
-+                UPDATE(ecmd.rx_pending,
-+                       ring->rx_pending == 0 ? ecmd.rx_max_pending : ring->rx_pending,
-+                       need_update);
- 
-         if (ring->rx_mini_pending_set)
--                UPDATE(ecmd.rx_mini_pending, ring->rx_mini_pending, need_update);
-+                UPDATE(ecmd.rx_mini_pending,
-+                       ring->rx_mini_pending == 0 ? ecmd.rx_mini_max_pending : ring->rx_mini_pending,
-+                       need_update);
- 
-         if (ring->rx_jumbo_pending_set)
--                UPDATE(ecmd.rx_jumbo_pending, ring->rx_jumbo_pending, need_update);
-+                UPDATE(ecmd.rx_jumbo_pending,
-+                       ring->rx_jumbo_pending == 0 ? ecmd.rx_jumbo_max_pending : ring->rx_jumbo_pending,
-+                       need_update);
- 
-         if (ring->tx_pending_set)
--                UPDATE(ecmd.tx_pending, ring->tx_pending, need_update);
-+                UPDATE(ecmd.tx_pending,
-+                       ring->tx_pending == 0 ? ecmd.tx_max_pending : ring->tx_pending,
-+                       need_update);
- 
-         if (!need_update)
-                 return 0;
-@@ -1037,16 +1045,20 @@ int config_parse_nic_buffer_size(
-         assert(rvalue);
-         assert(data);
- 
--        r = safe_atou32(rvalue, &k);
--        if (r < 0) {
--                log_syntax(unit, LOG_WARNING, filename, line, r,
--                           "Failed to parse interface buffer value, ignoring: %s", rvalue);
--                return 0;
--        }
--        if (k < 1) {
--                log_syntax(unit, LOG_WARNING, filename, line, 0,
--                           "Invalid %s= value, ignoring: %s", lvalue, rvalue);
--                return 0;
-+        if (streq(rvalue, "max"))
-+                k = 0;
-+        else {
-+                r = safe_atou32(rvalue, &k);
-+                if (r < 0) {
-+                        log_syntax(unit, LOG_WARNING, filename, line, r,
-+                                "Failed to parse interface buffer value, ignoring: %s", rvalue);
-+                        return 0;
-+                }
-+                if (k < 1) {
-+                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-+                                "Invalid %s= value, ignoring: %s", lvalue, rvalue);
-+                        return 0;
-+                }
-         }
- 
-         if (streq(lvalue, "RxBufferSize")) {
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index 7d28766624..aea131914e 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -70,6 +70,8 @@ typedef struct netdev_channels {
- } netdev_channels;
- 
- typedef struct netdev_ring_param {
-+        /* For any of the 4 following settings, a value of 0 indicates the hardware advertised maximum should
-+         * be used. */
-         uint32_t rx_pending;
-         uint32_t rx_mini_pending;
-         uint32_t rx_jumbo_pending;
--- 
-2.31.1
-
diff --git a/20472.patch b/20472.patch
deleted file mode 100644
index e5eb57b..0000000
--- a/20472.patch
+++ /dev/null
@@ -1,425 +0,0 @@
-From 78e57b79c8790448412acca41e5d4495366305a6 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 18 Aug 2021 16:41:11 +0900
-Subject: [PATCH] udev: make RxChannels= or friends also accept "max"
-
-Follow-up for 406041b7de767316674eb6a2f98ad466577ce8a4.
-
-Also, this makes
-- the settings accept an empty string,
-- if the specified value is too large, also use the advertised maximum
-  value.
-- mention the range of the value in the man page.
----
- man/systemd.link.xml                 |  49 ++------
- src/shared/ethtool-util.c            | 170 ++++++++++-----------------
- src/shared/ethtool-util.h            |  36 +++---
- src/udev/net/link-config-gperf.gperf |  16 +--
- 4 files changed, 90 insertions(+), 181 deletions(-)
-
-diff --git a/man/systemd.link.xml b/man/systemd.link.xml
-index fd744ebaed..dfb02073b2 100644
---- a/man/systemd.link.xml
-+++ b/man/systemd.link.xml
-@@ -710,58 +710,27 @@
-       </varlistentry>
-       <varlistentry>
-         <term><varname>RxChannels=</varname></term>
--        <listitem>
--          <para>Sets the number of receive channels (a number between 1 and 4294967295) .</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>TxChannels=</varname></term>
--        <listitem>
--          <para>Sets the number of transmit channels (a number between 1 and 4294967295).</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>OtherChannels=</varname></term>
--        <listitem>
--          <para>Sets the number of other channels (a number between 1 and 4294967295).</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>CombinedChannels=</varname></term>
-         <listitem>
--          <para>Sets the number of combined set channels (a number between 1 and 4294967295).</para>
-+          <para>Specifies the number of receive, transmit, other, or combined channels, respectively.
-+          Takes an unsigned integer in the range 1…4294967295 or <literal>max</literal>. If set to
-+          <literal>max</literal>, the advertised maximum value of the hardware will be used. When
-+          unset, the number will not be changed. Defaults to unset.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-         <term><varname>RxBufferSize=</varname></term>
--        <listitem>
--          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
--          in the NIC receive buffer. When unset, the kernel's default will be used. If set to
--          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>RxMiniBufferSize=</varname></term>
--        <listitem>
--          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
--          in the NIC mini receive buffer. When unset, the kernel's default will be used. If set to
--          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>RxJumboBufferSize=</varname></term>
--        <listitem>
--          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
--          in the NIC jumbo receive buffer. When unset, the kernel's default will be used. If set to
--          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
--        </listitem>
--      </varlistentry>
--      <varlistentry>
-         <term><varname>TxBufferSize=</varname></term>
-         <listitem>
--          <para>Takes an integer or <literal>max</literal>. Specifies the maximum number of pending packets
--          in the NIC transmit buffer. When unset, the kernel's default will be used. If set to
--          <literal>max</literal>, the hardware's advertised maximum size will be used.</para>
-+          <para>Specifies the maximum number of pending packets in the NIC receive buffer, mini receive
-+          buffer, jumbo receive buffer, or transmit buffer, respectively. Takes an unsigned integer in
-+          the range 1…4294967295 or <literal>max</literal>. If set to <literal>max</literal>, the
-+          advertised maximum value of the hardware will be used. When unset, the number will not be
-+          changed. Defaults to unset.</para>
-         </listitem>
-       </varlistentry>
-       <varlistentry>
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index ed251ec8dd..2d41d861ba 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -329,6 +329,17 @@ int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct et
-                 dest = _v;                             \
-         } while(false)
- 
-+#define UPDATE_WITH_MAX(dest, max, val, updated)       \
-+        do {                                           \
-+                typeof(dest) _v = (val);               \
-+                typeof(dest) _max = (max);             \
-+                if (_v == 0 || _v > _max)              \
-+                        _v = _max;                     \
-+                if (dest != _v)                        \
-+                        updated = true;                \
-+                dest = _v;                             \
-+        } while(false)
-+
- int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts) {
-         struct ethtool_wolinfo ecmd = {
-                 .cmd = ETHTOOL_GWOL,
-@@ -382,10 +393,10 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-         assert(ifname);
-         assert(ring);
- 
--        if (!ring->rx_pending_set &&
--            !ring->rx_mini_pending_set &&
--            !ring->rx_jumbo_pending_set &&
--            !ring->tx_pending_set)
-+        if (!ring->rx.set &&
-+            !ring->rx_mini.set &&
-+            !ring->rx_jumbo.set &&
-+            !ring->tx.set)
-                 return 0;
- 
-         r = ethtool_connect(ethtool_fd);
-@@ -398,25 +409,17 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-         if (r < 0)
-                 return -errno;
- 
--        if (ring->rx_pending_set)
--                UPDATE(ecmd.rx_pending,
--                       ring->rx_pending == 0 ? ecmd.rx_max_pending : ring->rx_pending,
--                       need_update);
-+        if (ring->rx.set)
-+                UPDATE_WITH_MAX(ecmd.rx_pending, ecmd.rx_max_pending, ring->rx.value, need_update);
- 
--        if (ring->rx_mini_pending_set)
--                UPDATE(ecmd.rx_mini_pending,
--                       ring->rx_mini_pending == 0 ? ecmd.rx_mini_max_pending : ring->rx_mini_pending,
--                       need_update);
-+        if (ring->rx_mini.set)
-+                UPDATE_WITH_MAX(ecmd.rx_mini_pending, ecmd.rx_mini_max_pending, ring->rx_mini.value, need_update);
- 
--        if (ring->rx_jumbo_pending_set)
--                UPDATE(ecmd.rx_jumbo_pending,
--                       ring->rx_jumbo_pending == 0 ? ecmd.rx_jumbo_max_pending : ring->rx_jumbo_pending,
--                       need_update);
-+        if (ring->rx_jumbo.set)
-+                UPDATE_WITH_MAX(ecmd.rx_jumbo_pending, ecmd.rx_jumbo_max_pending, ring->rx_jumbo.value, need_update);
- 
--        if (ring->tx_pending_set)
--                UPDATE(ecmd.tx_pending,
--                       ring->tx_pending == 0 ? ecmd.tx_max_pending : ring->tx_pending,
--                       need_update);
-+        if (ring->tx.set)
-+                UPDATE_WITH_MAX(ecmd.tx_pending, ecmd.tx_max_pending, ring->tx.value, need_update);
- 
-         if (!need_update)
-                 return 0;
-@@ -832,10 +835,10 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
-         assert(ifname);
-         assert(channels);
- 
--        if (!channels->rx_count_set &&
--            !channels->tx_count_set &&
--            !channels->other_count_set &&
--            !channels->combined_count_set)
-+        if (!channels->rx.set &&
-+            !channels->tx.set &&
-+            !channels->other.set &&
-+            !channels->combined.set)
-                 return 0;
- 
-         r = ethtool_connect(fd);
-@@ -848,17 +851,17 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
-         if (r < 0)
-                 return -errno;
- 
--        if (channels->rx_count_set)
--                UPDATE(ecmd.rx_count, channels->rx_count, need_update);
-+        if (channels->rx.set)
-+                UPDATE_WITH_MAX(ecmd.rx_count, ecmd.max_rx, channels->rx.value, need_update);
- 
--        if (channels->tx_count_set)
--                UPDATE(ecmd.tx_count, channels->tx_count, need_update);
-+        if (channels->tx.set)
-+                UPDATE_WITH_MAX(ecmd.tx_count, ecmd.max_tx, channels->tx.value, need_update);
- 
--        if (channels->other_count_set)
--                UPDATE(ecmd.other_count, channels->other_count, need_update);
-+        if (channels->other.set)
-+                UPDATE_WITH_MAX(ecmd.other_count, ecmd.max_other, channels->other.value, need_update);
- 
--        if (channels->combined_count_set)
--                UPDATE(ecmd.combined_count, channels->combined_count, need_update);
-+        if (channels->combined.set)
-+                UPDATE_WITH_MAX(ecmd.combined_count, ecmd.max_combined, channels->combined.value, need_update);
- 
-         if (!need_update)
-                 return 0;
-@@ -917,57 +920,6 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
-         return 0;
- }
- 
--int config_parse_channel(
--                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) {
--
--        netdev_channels *channels = data;
--        uint32_t k;
--        int r;
--
--        assert(filename);
--        assert(section);
--        assert(lvalue);
--        assert(rvalue);
--        assert(data);
--
--        r = safe_atou32(rvalue, &k);
--        if (r < 0) {
--                log_syntax(unit, LOG_WARNING, filename, line, r,
--                           "Failed to parse channel value for %s=, ignoring: %s", lvalue, rvalue);
--                return 0;
--        }
--        if (k < 1) {
--                log_syntax(unit, LOG_WARNING, filename, line, 0,
--                           "Invalid %s= value, ignoring: %s", lvalue, rvalue);
--                return 0;
--        }
--
--        if (streq(lvalue, "RxChannels")) {
--                channels->rx_count = k;
--                channels->rx_count_set = true;
--        } else if (streq(lvalue, "TxChannels")) {
--                channels->tx_count = k;
--                channels->tx_count_set = true;
--        } else if (streq(lvalue, "OtherChannels")) {
--                channels->other_count = k;
--                channels->other_count_set = true;
--        } else if (streq(lvalue, "CombinedChannels")) {
--                channels->combined_count = k;
--                channels->combined_count_set = true;
--        }
--
--        return 0;
--}
--
- int config_parse_advertise(
-                 const char *unit,
-                 const char *filename,
-@@ -1023,7 +975,7 @@ int config_parse_advertise(
-         }
- }
- 
--int config_parse_nic_buffer_size(
-+int config_parse_ring_buffer_or_channel(
-                 const char *unit,
-                 const char *filename,
-                 unsigned line,
-@@ -1035,7 +987,7 @@ int config_parse_nic_buffer_size(
-                 void *data,
-                 void *userdata) {
- 
--        netdev_ring_param *ring = data;
-+        u32_opt *dst = data;
-         uint32_t k;
-         int r;
- 
-@@ -1045,36 +997,32 @@ int config_parse_nic_buffer_size(
-         assert(rvalue);
-         assert(data);
- 
--        if (streq(rvalue, "max"))
--                k = 0;
--        else {
--                r = safe_atou32(rvalue, &k);
--                if (r < 0) {
--                        log_syntax(unit, LOG_WARNING, filename, line, r,
--                                "Failed to parse interface buffer value, ignoring: %s", rvalue);
--                        return 0;
--                }
--                if (k < 1) {
--                        log_syntax(unit, LOG_WARNING, filename, line, 0,
--                                "Invalid %s= value, ignoring: %s", lvalue, rvalue);
--                        return 0;
--                }
-+        if (isempty(rvalue)) {
-+                dst->value = 0;
-+                dst->set = false;
-+                return 0;
-+        }
-+
-+        if (streq(rvalue, "max")) {
-+                dst->value = 0;
-+                dst->set = true;
-+                return 0;
-         }
- 
--        if (streq(lvalue, "RxBufferSize")) {
--                ring->rx_pending = k;
--                ring->rx_pending_set = true;
--        } else if (streq(lvalue, "RxMiniBufferSize")) {
--                ring->rx_mini_pending = k;
--                ring->rx_mini_pending_set = true;
--        } else if (streq(lvalue, "RxJumboBufferSize")) {
--                ring->rx_jumbo_pending = k;
--                ring->rx_jumbo_pending_set = true;
--        } else if (streq(lvalue, "TxBufferSize")) {
--                ring->tx_pending = k;
--                ring->tx_pending_set = true;
-+        r = safe_atou32(rvalue, &k);
-+        if (r < 0) {
-+                log_syntax(unit, LOG_WARNING, filename, line, r,
-+                           "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
-+                return 0;
-+        }
-+        if (k < 1) {
-+                log_syntax(unit, LOG_WARNING, filename, line, 0,
-+                           "Invalid %s= value, ignoring: %s", lvalue, rvalue);
-+                return 0;
-         }
- 
-+        dst->value = k;
-+        dst->set = true;
-         return 0;
- }
- 
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index aea131914e..8fdbdec39a 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -57,30 +57,23 @@ struct ethtool_link_usettings {
-         } link_modes;
- };
- 
-+typedef struct u32_opt {
-+        uint32_t value; /* a value of 0 indicates the hardware advertised maximum should be used.*/
-+        bool set;
-+} u32_opt;
-+
- typedef struct netdev_channels {
--        uint32_t rx_count;
--        uint32_t tx_count;
--        uint32_t other_count;
--        uint32_t combined_count;
--
--        bool rx_count_set;
--        bool tx_count_set;
--        bool other_count_set;
--        bool combined_count_set;
-+        u32_opt rx;
-+        u32_opt tx;
-+        u32_opt other;
-+        u32_opt combined;
- } netdev_channels;
- 
- typedef struct netdev_ring_param {
--        /* For any of the 4 following settings, a value of 0 indicates the hardware advertised maximum should
--         * be used. */
--        uint32_t rx_pending;
--        uint32_t rx_mini_pending;
--        uint32_t rx_jumbo_pending;
--        uint32_t tx_pending;
--
--        bool rx_pending_set;
--        bool rx_mini_pending_set;
--        bool rx_jumbo_pending_set;
--        bool tx_pending_set;
-+        u32_opt rx;
-+        u32_opt rx_mini;
-+        u32_opt rx_jumbo;
-+        u32_opt tx;
- } netdev_ring_param;
- 
- int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret);
-@@ -111,6 +104,5 @@ enum ethtool_link_mode_bit_indices ethtool_link_mode_bit_from_string(const char
- CONFIG_PARSER_PROTOTYPE(config_parse_duplex);
- CONFIG_PARSER_PROTOTYPE(config_parse_wol);
- CONFIG_PARSER_PROTOTYPE(config_parse_port);
--CONFIG_PARSER_PROTOTYPE(config_parse_channel);
- CONFIG_PARSER_PROTOTYPE(config_parse_advertise);
--CONFIG_PARSER_PROTOTYPE(config_parse_nic_buffer_size);
-+CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
-diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
-index e2f07d758b..d0190da5cb 100644
---- a/src/udev/net/link-config-gperf.gperf
-+++ b/src/udev/net/link-config-gperf.gperf
-@@ -58,15 +58,15 @@ Link.TCP6SegmentationOffload,          config_parse_tristate,                 0,
- Link.UDPSegmentationOffload,           config_parse_warn_compat,              DISABLED_LEGACY,               0
- Link.GenericReceiveOffload,            config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
- Link.LargeReceiveOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
--Link.RxChannels,                       config_parse_channel,                  0,                             offsetof(LinkConfig, channels)
--Link.TxChannels,                       config_parse_channel,                  0,                             offsetof(LinkConfig, channels)
--Link.OtherChannels,                    config_parse_channel,                  0,                             offsetof(LinkConfig, channels)
--Link.CombinedChannels,                 config_parse_channel,                  0,                             offsetof(LinkConfig, channels)
-+Link.RxChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
-+Link.TxChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
-+Link.OtherChannels,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.other)
-+Link.CombinedChannels,                 config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.combined)
- Link.Advertise,                        config_parse_advertise,                0,                             offsetof(LinkConfig, advertise)
--Link.RxBufferSize,                     config_parse_nic_buffer_size,          0,                             offsetof(LinkConfig, ring)
--Link.RxMiniBufferSize,                 config_parse_nic_buffer_size,          0,                             offsetof(LinkConfig, ring)
--Link.RxJumboBufferSize,                config_parse_nic_buffer_size,          0,                             offsetof(LinkConfig, ring)
--Link.TxBufferSize,                     config_parse_nic_buffer_size,          0,                             offsetof(LinkConfig, ring)
-+Link.RxBufferSize,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx)
-+Link.RxMiniBufferSize,                 config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_mini)
-+Link.RxJumboBufferSize,                config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_jumbo)
-+Link.TxBufferSize,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.tx)
- Link.RxFlowControl,                    config_parse_tristate,                 0,                             offsetof(LinkConfig, rx_flow_control)
- Link.TxFlowControl,                    config_parse_tristate,                 0,                             offsetof(LinkConfig, tx_flow_control)
- Link.AutoNegotiationFlowControl,       config_parse_tristate,                 0,                             offsetof(LinkConfig, autoneg_flow_control)
--- 
-2.31.1
-
diff --git a/20477.patch b/20477.patch
deleted file mode 100644
index 6676bff..0000000
--- a/20477.patch
+++ /dev/null
@@ -1,561 +0,0 @@
-From a1661a140c97a9e8fd90ee00f2de6baa214c9076 Mon Sep 17 00:00:00 2001
-From: Daan De Meyer <daan.j.demeyer@gmail.com>
-Date: Wed, 18 Aug 2021 13:52:00 +0100
-Subject: [PATCH] udev: Add support for configuring nic coalescing settings
-
-These are configured via the corresponding ethtool ioctl.
----
- man/systemd.link.xml                       |  71 +++++++
- src/shared/ethtool-util.c                  | 205 +++++++++++++++++++++
- src/shared/ethtool-util.h                  |  29 +++
- src/udev/net/link-config-gperf.gperf       | 124 ++++++++-----
- src/udev/net/link-config.c                 |   4 +
- src/udev/net/link-config.h                 |   1 +
- test/fuzz/fuzz-link-parser/directives.link |  22 +++
- 7 files changed, 405 insertions(+), 51 deletions(-)
-
-diff --git a/man/systemd.link.xml b/man/systemd.link.xml
-index dfb02073b2..6d8dcb9af7 100644
---- a/man/systemd.link.xml
-+++ b/man/systemd.link.xml
-@@ -773,6 +773,77 @@
-           accept. An unsigned integer in the range 1…65535. Defaults to unset.</para>
-         </listitem>
-       </varlistentry>
-+      <varlistentry>
-+        <term><varname>UseAdaptiveRxCoalesce=</varname></term>
-+        <term><varname>UseAdaptiveTxCoalesce=</varname></term>
-+        <listitem>
-+          <para>Boolean properties that, when set, enable/disable adaptive Rx/Tx coalescing if the hardware
-+          supports it. When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>RxCoalesceSec=</varname></term>
-+        <term><varname>RxCoalesceIrqSec=</varname></term>
-+        <term><varname>RxCoalesceLowSec=</varname></term>
-+        <term><varname>RxCoalesceHighSec=</varname></term>
-+        <term><varname>TxCoalesceSec=</varname></term>
-+        <term><varname>TxCoalesceIrqSec=</varname></term>
-+        <term><varname>TxCoalesceLowSec=</varname></term>
-+        <term><varname>TxCoalesceHighSec=</varname></term>
-+        <listitem>
-+          <para>These properties configure the delay before Rx/Tx interrupts are generated after a packet is
-+          sent/received. The <literal>Irq</literal> properties come into effect when the host is servicing an
-+          IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into effect when the
-+          packet rate drops below the low packet rate threshold or exceeds the high packet rate threshold
-+          respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's defaults will be
-+          used.</para>
-+        </listitem>
-+      </varlistentry>
-+        <varlistentry>
-+        <term><varname>RxMaxCoalescedFrames=</varname></term>
-+        <term><varname>RxMaxCoalescedIrqFrames=</varname></term>
-+        <term><varname>RxMaxCoalescedLowFrames=</varname></term>
-+        <term><varname>RxMaxCoalescedHighFrames=</varname></term>
-+        <term><varname>TxMaxCoalescedFrames=</varname></term>
-+        <term><varname>TxMaxCoalescedIrqFrames=</varname></term>
-+        <term><varname>TxMaxCoalescedLowFrames=</varname></term>
-+        <term><varname>TxMaxCoalescedHighFrames=</varname></term>
-+        <listitem>
-+          <para>These properties configure the maximum number of frames that are sent/received before a Rx/Tx
-+          interrupt is generated. The <literal>Irq</literal> properties come into effect when the host is
-+          servicing an IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into
-+          effect when the packet rate drops below the low packet rate threshold or exceeds the high packet
-+          rate threshold respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's
-+          defaults will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>CoalescePacketRateLow=</varname></term>
-+        <term><varname>CoalescePacketRateHigh=</varname></term>
-+        <listitem>
-+          <para>These properties configure the low and high packet rate (expressed in packets per second)
-+          threshold respectively and are used to determine when the corresponding coalescing settings for low
-+          and high packet rates come into effect if adaptive Rx/Tx coalescing is enabled. If unset, the
-+          kernel's defaults will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>CoalescePacketRateSampleIntervalSec=</varname></term>
-+        <listitem>
-+          <para>Configures how often to sample the packet rate used for adaptive Rx/Tx coalescing. This
-+          property cannot be zero. This lowest time granularity supported by this property is seconds.
-+          Partial seconds will be rounded up before being passed to the kernel. If unset, the kernel's
-+          default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>StatisticsBlockCoalesceSec=</varname></term>
-+        <listitem>
-+          <para>How long to delay driver in-memory statistics block updates. If the driver does not have an
-+          in-memory statistic block, this property is ignored. This property cannot be zero. If unset, the
-+          kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
- 
-     </variablelist>
-   </refsect1>
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index 2d41d861ba..f7f553dd29 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -14,6 +14,7 @@
- #include "memory-util.h"
- #include "socket-util.h"
- #include "string-table.h"
-+#include "strv.h"
- #include "strxcpyx.h"
- 
- static const char* const duplex_table[_DUP_MAX] = {
-@@ -1091,3 +1092,207 @@ int config_parse_wol(
- 
-         return 0;
- }
-+
-+int config_parse_coalesce_u32(
-+                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) {
-+        u32_opt *dst = data;
-+        uint32_t k;
-+        int r;
-+
-+        if (isempty(rvalue)) {
-+                dst->value = 0;
-+                dst->set = false;
-+                return 0;
-+        }
-+
-+        r = safe_atou32(rvalue, &k);
-+        if (r < 0) {
-+                log_syntax(unit, LOG_WARNING, filename, line, r,
-+                           "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
-+                return 0;
-+        }
-+
-+        dst->value = k;
-+        dst->set = true;
-+        return 0;
-+}
-+
-+int config_parse_coalesce_sec(
-+                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) {
-+        u32_opt *dst = data;
-+        usec_t usec;
-+        int r;
-+
-+        if (isempty(rvalue)) {
-+                dst->value = 0;
-+                dst->set = false;
-+                return 0;
-+        }
-+
-+        r = parse_sec(rvalue, &usec);
-+        if (r < 0) {
-+                log_syntax(unit, LOG_WARNING, filename, line, r,
-+                           "Failed to parse coalesce setting value, ignoring: %s", rvalue);
-+                return 0;
-+        }
-+
-+        if (usec > UINT32_MAX) {
-+                log_syntax(unit, LOG_WARNING, filename, line, 0,
-+                           "Too large %s= value, ignoring: %s", lvalue, rvalue);
-+                return 0;
-+        }
-+
-+        if (STR_IN_SET(lvalue, "StatisticsBlockCoalesceSec", "CoalescePacketRateSampleIntervalSec") && usec < 1) {
-+                log_syntax(unit, LOG_WARNING, filename, line, 0,
-+                           "Invalid %s= value, ignoring: %s", lvalue, rvalue);
-+                return 0;
-+        }
-+
-+        dst->value = (uint32_t) usec;
-+        dst->set = true;
-+
-+        return 0;
-+}
-+
-+int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce) {
-+        struct ethtool_coalesce ecmd = {
-+                .cmd = ETHTOOL_GCOALESCE,
-+        };
-+        struct ifreq ifr = {
-+                .ifr_data = (void*) &ecmd,
-+        };
-+        bool need_update = false;
-+        int r;
-+
-+        assert(ethtool_fd);
-+        assert(ifname);
-+        assert(coalesce);
-+
-+        if (coalesce->use_adaptive_rx_coalesce < 0 &&
-+            coalesce->use_adaptive_tx_coalesce < 0 &&
-+            !coalesce->rx_coalesce_usecs.set &&
-+            !coalesce->rx_max_coalesced_frames.set &&
-+            !coalesce->rx_coalesce_usecs_irq.set &&
-+            !coalesce->rx_max_coalesced_frames_irq.set &&
-+            !coalesce->tx_coalesce_usecs.set &&
-+            !coalesce->tx_max_coalesced_frames.set &&
-+            !coalesce->tx_coalesce_usecs_irq.set &&
-+            !coalesce->tx_max_coalesced_frames_irq.set &&
-+            !coalesce->stats_block_coalesce_usecs.set &&
-+            !coalesce->pkt_rate_low.set &&
-+            !coalesce->rx_coalesce_usecs_low.set &&
-+            !coalesce->rx_max_coalesced_frames_low.set &&
-+            !coalesce->tx_coalesce_usecs_low.set &&
-+            !coalesce->tx_max_coalesced_frames_low.set &&
-+            !coalesce->pkt_rate_high.set &&
-+            !coalesce->rx_coalesce_usecs_high.set &&
-+            !coalesce->rx_max_coalesced_frames_high.set &&
-+            !coalesce->tx_coalesce_usecs_high.set &&
-+            !coalesce->tx_max_coalesced_frames_high.set &&
-+            !coalesce->rate_sample_interval.set)
-+                return 0;
-+
-+        r = ethtool_connect(ethtool_fd);
-+        if (r < 0)
-+                return r;
-+
-+        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+
-+        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-+        if (r < 0)
-+                return -errno;
-+
-+        if (coalesce->use_adaptive_rx_coalesce >= 0)
-+                UPDATE(ecmd.use_adaptive_rx_coalesce, (uint32_t) coalesce->use_adaptive_rx_coalesce, need_update);
-+
-+        if (coalesce->use_adaptive_tx_coalesce >= 0)
-+                UPDATE(ecmd.use_adaptive_tx_coalesce, (uint32_t) coalesce->use_adaptive_tx_coalesce, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs.set)
-+                UPDATE(ecmd.rx_coalesce_usecs, coalesce->rx_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames, coalesce->rx_max_coalesced_frames.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_irq.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_irq, coalesce->rx_coalesce_usecs_irq.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_irq.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_irq, coalesce->rx_max_coalesced_frames_irq.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs.set)
-+                UPDATE(ecmd.tx_coalesce_usecs, coalesce->tx_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames, coalesce->tx_max_coalesced_frames.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_irq.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_irq, coalesce->tx_coalesce_usecs_irq.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_irq.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_irq, coalesce->tx_max_coalesced_frames_irq.value, need_update);
-+
-+        if (coalesce->stats_block_coalesce_usecs.set)
-+                UPDATE(ecmd.stats_block_coalesce_usecs, coalesce->stats_block_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->pkt_rate_low.set)
-+                UPDATE(ecmd.pkt_rate_low, coalesce->pkt_rate_low.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_low.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_low, coalesce->rx_coalesce_usecs_low.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_low.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_low, coalesce->rx_max_coalesced_frames_low.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_low.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_low, coalesce->tx_coalesce_usecs_low.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_low.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_low, coalesce->tx_max_coalesced_frames_low.value, need_update);
-+
-+        if (coalesce->pkt_rate_high.set)
-+                UPDATE(ecmd.pkt_rate_high, coalesce->pkt_rate_high.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_high.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_high, coalesce->rx_coalesce_usecs_high.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_high.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_high, coalesce->rx_max_coalesced_frames_high.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_high.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_high, coalesce->tx_coalesce_usecs_high.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_high.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_high, coalesce->tx_max_coalesced_frames_high.value, need_update);
-+
-+        if (coalesce->rate_sample_interval.set)
-+                UPDATE(ecmd.rate_sample_interval, DIV_ROUND_UP(coalesce->rate_sample_interval.value, USEC_PER_SEC), need_update);
-+
-+        if (!need_update)
-+                return 0;
-+
-+        ecmd.cmd = ETHTOOL_SCOALESCE;
-+        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-+        if (r < 0)
-+                return -errno;
-+
-+        return 0;
-+}
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index 8fdbdec39a..bb0333775c 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -76,6 +76,31 @@ typedef struct netdev_ring_param {
-         u32_opt tx;
- } netdev_ring_param;
- 
-+typedef struct netdev_coalesce_param {
-+        u32_opt rx_coalesce_usecs;
-+        u32_opt rx_max_coalesced_frames;
-+        u32_opt rx_coalesce_usecs_irq;
-+        u32_opt rx_max_coalesced_frames_irq;
-+        u32_opt tx_coalesce_usecs;
-+        u32_opt tx_max_coalesced_frames;
-+        u32_opt tx_coalesce_usecs_irq;
-+        u32_opt tx_max_coalesced_frames_irq;
-+        u32_opt stats_block_coalesce_usecs;
-+        int use_adaptive_rx_coalesce;
-+        int use_adaptive_tx_coalesce;
-+        u32_opt pkt_rate_low;
-+        u32_opt rx_coalesce_usecs_low;
-+        u32_opt rx_max_coalesced_frames_low;
-+        u32_opt tx_coalesce_usecs_low;
-+        u32_opt tx_max_coalesced_frames_low;
-+        u32_opt pkt_rate_high;
-+        u32_opt rx_coalesce_usecs_high;
-+        u32_opt rx_max_coalesced_frames_high;
-+        u32_opt tx_coalesce_usecs_high;
-+        u32_opt tx_max_coalesced_frames_high;
-+        u32_opt rate_sample_interval;
-+} netdev_coalesce_param;
-+
- int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret);
- int ethtool_get_link_info(int *ethtool_fd, const char *ifname,
-                           int *ret_autonegotiation, uint64_t *ret_speed,
-@@ -89,6 +114,7 @@ int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname,
-                               uint64_t speed, Duplex duplex, NetDevPort port);
- int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels);
- int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg);
-+int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce);
- 
- const char *duplex_to_string(Duplex d) _const_;
- Duplex duplex_from_string(const char *d) _pure_;
-@@ -106,3 +132,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wol);
- CONFIG_PARSER_PROTOTYPE(config_parse_port);
- CONFIG_PARSER_PROTOTYPE(config_parse_advertise);
- CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
-+CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_u32);
-+CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_sec);
-+CONFIG_PARSER_PROTOTYPE(config_parse_nic_coalesce_setting);
-diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
-index d0190da5cb..f800de8386 100644
---- a/src/udev/net/link-config-gperf.gperf
-+++ b/src/udev/net/link-config-gperf.gperf
-@@ -21,54 +21,76 @@ struct ConfigPerfItem;
- %struct-type
- %includes
- %%
--Match.MACAddress,                      config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.mac)
--Match.PermanentMACAddress,             config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.permanent_mac)
--Match.OriginalName,                    config_parse_match_ifnames,            0,                             offsetof(LinkConfig, match.ifname)
--Match.Path,                            config_parse_match_strv,               0,                             offsetof(LinkConfig, match.path)
--Match.Driver,                          config_parse_match_strv,               0,                             offsetof(LinkConfig, match.driver)
--Match.Type,                            config_parse_match_strv,               0,                             offsetof(LinkConfig, match.iftype)
--Match.Property,                        config_parse_match_property,           0,                             offsetof(LinkConfig, match.property)
--Match.Host,                            config_parse_net_condition,            CONDITION_HOST,                offsetof(LinkConfig, conditions)
--Match.Virtualization,                  config_parse_net_condition,            CONDITION_VIRTUALIZATION,      offsetof(LinkConfig, conditions)
--Match.KernelCommandLine,               config_parse_net_condition,            CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
--Match.KernelVersion,                   config_parse_net_condition,            CONDITION_KERNEL_VERSION,      offsetof(LinkConfig, conditions)
--Match.Architecture,                    config_parse_net_condition,            CONDITION_ARCHITECTURE,        offsetof(LinkConfig, conditions)
--Link.Description,                      config_parse_string,                   0,                             offsetof(LinkConfig, description)
--Link.MACAddressPolicy,                 config_parse_mac_address_policy,       0,                             offsetof(LinkConfig, mac_address_policy)
--Link.MACAddress,                       config_parse_hwaddr,                   0,                             offsetof(LinkConfig, mac)
--Link.NamePolicy,                       config_parse_name_policy,              0,                             offsetof(LinkConfig, name_policy)
--Link.Name,                             config_parse_ifname,                   0,                             offsetof(LinkConfig, name)
--Link.AlternativeName,                  config_parse_ifnames,                  IFNAME_VALID_ALTERNATIVE,      offsetof(LinkConfig, alternative_names)
--Link.AlternativeNamesPolicy,           config_parse_alternative_names_policy, 0,                             offsetof(LinkConfig, alternative_names_policy)
--Link.Alias,                            config_parse_ifalias,                  0,                             offsetof(LinkConfig, alias)
--Link.TransmitQueues,                   config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, txqueues)
--Link.ReceiveQueues,                    config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, rxqueues)
--Link.TransmitQueueLength,              config_parse_txqueuelen,               0,                             offsetof(LinkConfig, txqueuelen)
--Link.MTUBytes,                         config_parse_mtu,                      AF_UNSPEC,                     offsetof(LinkConfig, mtu)
--Link.BitsPerSecond,                    config_parse_si_uint64,                0,                             offsetof(LinkConfig, speed)
--Link.Duplex,                           config_parse_duplex,                   0,                             offsetof(LinkConfig, duplex)
--Link.AutoNegotiation,                  config_parse_tristate,                 0,                             offsetof(LinkConfig, autonegotiation)
--Link.WakeOnLan,                        config_parse_wol,                      0,                             offsetof(LinkConfig, wol)
--Link.Port,                             config_parse_port,                     0,                             offsetof(LinkConfig, port)
--Link.ReceiveChecksumOffload,           config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
--Link.TransmitChecksumOffload,          config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
--Link.GenericSegmentationOffload,       config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
--Link.TCPSegmentationOffload,           config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
--Link.TCP6SegmentationOffload,          config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
--Link.UDPSegmentationOffload,           config_parse_warn_compat,              DISABLED_LEGACY,               0
--Link.GenericReceiveOffload,            config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
--Link.LargeReceiveOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
--Link.RxChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
--Link.TxChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
--Link.OtherChannels,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.other)
--Link.CombinedChannels,                 config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.combined)
--Link.Advertise,                        config_parse_advertise,                0,                             offsetof(LinkConfig, advertise)
--Link.RxBufferSize,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx)
--Link.RxMiniBufferSize,                 config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_mini)
--Link.RxJumboBufferSize,                config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_jumbo)
--Link.TxBufferSize,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.tx)
--Link.RxFlowControl,                    config_parse_tristate,                 0,                             offsetof(LinkConfig, rx_flow_control)
--Link.TxFlowControl,                    config_parse_tristate,                 0,                             offsetof(LinkConfig, tx_flow_control)
--Link.AutoNegotiationFlowControl,       config_parse_tristate,                 0,                             offsetof(LinkConfig, autoneg_flow_control)
--Link.GenericSegmentOffloadMaxBytes,    config_parse_iec_size,                 0,                             offsetof(LinkConfig, gso_max_size)
--Link.GenericSegmentOffloadMaxSegments, config_parse_uint32,                   0,                             offsetof(LinkConfig, gso_max_segments)
-+Match.MACAddress,                         config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.mac)
-+Match.PermanentMACAddress,                config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.permanent_mac)
-+Match.OriginalName,                       config_parse_match_ifnames,            0,                             offsetof(LinkConfig, match.ifname)
-+Match.Path,                               config_parse_match_strv,               0,                             offsetof(LinkConfig, match.path)
-+Match.Driver,                             config_parse_match_strv,               0,                             offsetof(LinkConfig, match.driver)
-+Match.Type,                               config_parse_match_strv,               0,                             offsetof(LinkConfig, match.iftype)
-+Match.Property,                           config_parse_match_property,           0,                             offsetof(LinkConfig, match.property)
-+Match.Host,                               config_parse_net_condition,            CONDITION_HOST,                offsetof(LinkConfig, conditions)
-+Match.Virtualization,                     config_parse_net_condition,            CONDITION_VIRTUALIZATION,      offsetof(LinkConfig, conditions)
-+Match.KernelCommandLine,                  config_parse_net_condition,            CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
-+Match.KernelVersion,                      config_parse_net_condition,            CONDITION_KERNEL_VERSION,      offsetof(LinkConfig, conditions)
-+Match.Architecture,                       config_parse_net_condition,            CONDITION_ARCHITECTURE,        offsetof(LinkConfig, conditions)
-+Link.Description,                         config_parse_string,                   0,                             offsetof(LinkConfig, description)
-+Link.MACAddressPolicy,                    config_parse_mac_address_policy,       0,                             offsetof(LinkConfig, mac_address_policy)
-+Link.MACAddress,                          config_parse_hwaddr,                   0,                             offsetof(LinkConfig, mac)
-+Link.NamePolicy,                          config_parse_name_policy,              0,                             offsetof(LinkConfig, name_policy)
-+Link.Name,                                config_parse_ifname,                   0,                             offsetof(LinkConfig, name)
-+Link.AlternativeName,                     config_parse_ifnames,                  IFNAME_VALID_ALTERNATIVE,      offsetof(LinkConfig, alternative_names)
-+Link.AlternativeNamesPolicy,              config_parse_alternative_names_policy, 0,                             offsetof(LinkConfig, alternative_names_policy)
-+Link.Alias,                               config_parse_ifalias,                  0,                             offsetof(LinkConfig, alias)
-+Link.TransmitQueues,                      config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, txqueues)
-+Link.ReceiveQueues,                       config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, rxqueues)
-+Link.TransmitQueueLength,                 config_parse_txqueuelen,               0,                             offsetof(LinkConfig, txqueuelen)
-+Link.MTUBytes,                            config_parse_mtu,                      AF_UNSPEC,                     offsetof(LinkConfig, mtu)
-+Link.BitsPerSecond,                       config_parse_si_uint64,                0,                             offsetof(LinkConfig, speed)
-+Link.Duplex,                              config_parse_duplex,                   0,                             offsetof(LinkConfig, duplex)
-+Link.AutoNegotiation,                     config_parse_tristate,                 0,                             offsetof(LinkConfig, autonegotiation)
-+Link.WakeOnLan,                           config_parse_wol,                      0,                             offsetof(LinkConfig, wol)
-+Link.Port,                                config_parse_port,                     0,                             offsetof(LinkConfig, port)
-+Link.ReceiveChecksumOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
-+Link.TransmitChecksumOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
-+Link.GenericSegmentationOffload,          config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
-+Link.TCPSegmentationOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
-+Link.TCP6SegmentationOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
-+Link.UDPSegmentationOffload,              config_parse_warn_compat,              DISABLED_LEGACY,               0
-+Link.GenericReceiveOffload,               config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
-+Link.LargeReceiveOffload,                 config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
-+Link.RxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
-+Link.TxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
-+Link.OtherChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.other)
-+Link.CombinedChannels,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.combined)
-+Link.Advertise,                           config_parse_advertise,                0,                             offsetof(LinkConfig, advertise)
-+Link.RxBufferSize,                        config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx)
-+Link.RxMiniBufferSize,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_mini)
-+Link.RxJumboBufferSize,                   config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_jumbo)
-+Link.TxBufferSize,                        config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.tx)
-+Link.RxFlowControl,                       config_parse_tristate,                 0,                             offsetof(LinkConfig, rx_flow_control)
-+Link.TxFlowControl,                       config_parse_tristate,                 0,                             offsetof(LinkConfig, tx_flow_control)
-+Link.AutoNegotiationFlowControl,          config_parse_tristate,                 0,                             offsetof(LinkConfig, autoneg_flow_control)
-+Link.GenericSegmentOffloadMaxBytes,       config_parse_iec_size,                 0,                             offsetof(LinkConfig, gso_max_size)
-+Link.GenericSegmentOffloadMaxSegments,    config_parse_uint32,                   0,                             offsetof(LinkConfig, gso_max_segments)
-+Link.RxCoalesceSec,                       config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
-+Link.RxMaxCoalescedFrames,                config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
-+Link.RxCoalesceIrqSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
-+Link.RxMaxCoalescedIrqFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_irq)
-+Link.TxCoalesceSec,                       config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs)
-+Link.TxMaxCoalescedFrames,                config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames)
-+Link.TxCoalesceIrqSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_irq)
-+Link.TxMaxCoalescedIrqFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_irq)
-+Link.StatisticsBlockCoalesceSec,          config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.stats_block_coalesce_usecs)
-+Link.UseAdaptiveRxCoalesce,               config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_rx_coalesce)
-+Link.UseAdaptiveTxCoalesce,               config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_tx_coalesce)
-+Link.CoalescePacketRateLow,               config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_low)
-+Link.RxCoalesceLowSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_low)
-+Link.RxMaxCoalescedLowFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_low)
-+Link.TxCoalesceLowSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_low)
-+Link.TxMaxCoalescedLowFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_low)
-+Link.CoalescePacketRateHigh,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_high)
-+Link.RxCoalesceHighSec,                   config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_high)
-+Link.RxMaxCoalescedHighFrames,            config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_high)
-+Link.TxCoalesceHighSec,                   config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
-+Link.TxMaxCoalescedHighFrames,            config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
-+Link.CoalescePacketRateSampleIntervalSec, config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rate_sample_interval)
-diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
-index 8dfe23691b..9451bd8b66 100644
---- a/src/udev/net/link-config.c
-+++ b/src/udev/net/link-config.c
-@@ -353,6 +353,10 @@ static int link_config_apply_ethtool_settings(int *ethtool_fd, const LinkConfig
-         if (r < 0)
-                 log_device_warning_errno(device, r, "Could not set flow control, ignoring: %m");
- 
-+        r = ethtool_set_nic_coalesce_settings(ethtool_fd, name, &config->coalesce);
-+        if (r < 0)
-+                log_device_warning_errno(device, r, "Could not set coalesce settings, ignoring: %m");
-+
-         return 0;
- }
- 
-diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
-index b505c94f95..8a29a92822 100644
---- a/src/udev/net/link-config.h
-+++ b/src/udev/net/link-config.h
-@@ -64,6 +64,7 @@ struct LinkConfig {
-         int rx_flow_control;
-         int tx_flow_control;
-         int autoneg_flow_control;
-+        netdev_coalesce_param coalesce;
- 
-         LIST_FIELDS(LinkConfig, links);
- };
-diff --git a/test/fuzz/fuzz-link-parser/directives.link b/test/fuzz/fuzz-link-parser/directives.link
-index 112a81930f..5f232ce698 100644
---- a/test/fuzz/fuzz-link-parser/directives.link
-+++ b/test/fuzz/fuzz-link-parser/directives.link
-@@ -51,3 +51,25 @@ TxFlowControl=
- AutoNegotiationFlowControl=
- GenericSegmentOffloadMaxBytes=
- GenericSegmentOffloadMaxSegments=
-+RxCoalesceSec=
-+RxMaxCoalescedFrames=
-+RxCoalesceIrqSec=
-+RxMaxCoalescedIrqFrames=
-+TxCoalesceSec=
-+TxMaxCoalescedFrames=
-+TxCoalesceIrqSec=
-+TxMaxCoalescedIrqFrames=
-+StatisticsBlockCoalesceSec=
-+UseAdaptiveRxCoalesce=
-+UseAdaptiveTxCoalesce=
-+CoalescePacketRateLow=
-+RxCoalesceLowSec=
-+RxMaxCoalescedLowFrames=
-+TxCoalesceLowSec=
-+TxMaxCoalescedLowFrames=
-+CoalescePacketRateHigh=
-+RxCoalesceHighSec=
-+RxMaxCoalescedHighFrames=
-+TxCoalesceHighSec=
-+TxMaxCoalescedHighFrames=
-+CoalescePacketRateSampleIntervalSec=
--- 
-2.31.1
-
diff --git a/20484.patch b/20484.patch
deleted file mode 100644
index 9da073b..0000000
--- a/20484.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 0e5c20b7a4f47fd3f8edbc2735810ea3513360bb Mon Sep 17 00:00:00 2001
-From: Daan De Meyer <daan.j.demeyer@gmail.com>
-Date: Thu, 19 Aug 2021 13:44:35 +0100
-Subject: [PATCH] link: Add support for rx-gro-hw nic feature
-
----
- man/systemd.link.xml                       |  7 +++++++
- src/shared/ethtool-util.c                  | 15 ++++++++-------
- src/shared/ethtool-util.h                  |  1 +
- src/udev/net/link-config-gperf.gperf       |  1 +
- test/fuzz/fuzz-link-parser/directives.link |  1 +
- 5 files changed, 18 insertions(+), 7 deletions(-)
-
-diff --git a/man/systemd.link.xml b/man/systemd.link.xml
-index 6d8dcb9af7..638a1522cd 100644
---- a/man/systemd.link.xml
-+++ b/man/systemd.link.xml
-@@ -701,6 +701,13 @@
-           When unset, the kernel's default will be used.</para>
-         </listitem>
-       </varlistentry>
-+      <varlistentry>
-+        <term><varname>GenericReceiveOffloadHardware=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, hardware accelerated Generic Receive Offload (GRO) is
-+          enabled. When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-       <varlistentry>
-         <term><varname>LargeReceiveOffload=</varname></term>
-         <listitem>
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index f7f553dd29..a08bb2b7f5 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -70,13 +70,14 @@ DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
- DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
- 
- static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
--        [NET_DEV_FEAT_RX]   = "rx-checksum",
--        [NET_DEV_FEAT_TX]   = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
--        [NET_DEV_FEAT_GSO]  = "tx-generic-segmentation",
--        [NET_DEV_FEAT_GRO]  = "rx-gro",
--        [NET_DEV_FEAT_LRO]  = "rx-lro",
--        [NET_DEV_FEAT_TSO]  = "tx-tcp-segmentation",
--        [NET_DEV_FEAT_TSO6] = "tx-tcp6-segmentation",
-+        [NET_DEV_FEAT_RX]     = "rx-checksum",
-+        [NET_DEV_FEAT_TX]     = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
-+        [NET_DEV_FEAT_GSO]    = "tx-generic-segmentation",
-+        [NET_DEV_FEAT_GRO]    = "rx-gro",
-+        [NET_DEV_FEAT_GRO_HW] = "rx-gro-hw",
-+        [NET_DEV_FEAT_LRO]    = "rx-lro",
-+        [NET_DEV_FEAT_TSO]    = "tx-tcp-segmentation",
-+        [NET_DEV_FEAT_TSO6]   = "tx-tcp6-segmentation",
- };
- 
- static const char* const ethtool_link_mode_bit_table[] = {
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index bb0333775c..2181ab6fd6 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -23,6 +23,7 @@ typedef enum NetDevFeature {
-         NET_DEV_FEAT_TX,
-         NET_DEV_FEAT_GSO,
-         NET_DEV_FEAT_GRO,
-+        NET_DEV_FEAT_GRO_HW,
-         NET_DEV_FEAT_LRO,
-         NET_DEV_FEAT_TSO,
-         NET_DEV_FEAT_TSO6,
-diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
-index f800de8386..44b46cb17c 100644
---- a/src/udev/net/link-config-gperf.gperf
-+++ b/src/udev/net/link-config-gperf.gperf
-@@ -57,6 +57,7 @@ Link.TCPSegmentationOffload,              config_parse_tristate,
- Link.TCP6SegmentationOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
- Link.UDPSegmentationOffload,              config_parse_warn_compat,              DISABLED_LEGACY,               0
- Link.GenericReceiveOffload,               config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
-+Link.GenericReceiveOffloadHardware,       config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_HW])
- Link.LargeReceiveOffload,                 config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
- Link.RxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
- Link.TxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
-diff --git a/test/fuzz/fuzz-link-parser/directives.link b/test/fuzz/fuzz-link-parser/directives.link
-index 5f232ce698..b5cffb1a27 100644
---- a/test/fuzz/fuzz-link-parser/directives.link
-+++ b/test/fuzz/fuzz-link-parser/directives.link
-@@ -36,6 +36,7 @@ TCPSegmentationOffload=
- TCP6SegmentationOffload=
- UDPSegmentationOffload=
- GenericReceiveOffload=
-+GenericReceiveOffloadHardware=
- LargeReceiveOffload=
- RxChannels=
- TxChannels=
--- 
-2.31.1
-
diff --git a/20489.patch b/20489.patch
deleted file mode 100644
index 0b4f8d9..0000000
--- a/20489.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 0a377494bcfcf4e145e260478071be124d56dc6d Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Fri, 20 Aug 2021 09:41:34 +0900
-Subject: [PATCH] network: add UseMTU= in [IPv6AcceptRA]
-
-Note that kernel has similar knob in sysctl: accept_ra_mtu.
-
-Closes #18868.
----
- man/systemd.network.xml                          |  8 ++++++++
- src/network/networkd-ndisc.c                     | 14 +++++++-------
- src/network/networkd-network-gperf.gperf         |  1 +
- src/network/networkd-network.c                   |  3 ++-
- src/network/networkd-network.h                   |  1 +
- test/fuzz/fuzz-network-parser/directives.network |  1 +
- 6 files changed, 20 insertions(+), 8 deletions(-)
-
-diff --git a/man/systemd.network.xml b/man/systemd.network.xml
-index 03100c035b84..573ba959eb4d 100644
---- a/man/systemd.network.xml
-+++ b/man/systemd.network.xml
-@@ -2265,6 +2265,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
-           </listitem>
-         </varlistentry>
- 
-+        <varlistentry>
-+          <term><varname>UseMTU=</varname></term>
-+          <listitem>
-+            <para>Takes a boolean. When true, the MTU received in the Router Advertisement will be
-+            used. Defaults to true.</para>
-+          </listitem>
-+        </varlistentry>
-+
-         <varlistentry>
-           <term><varname>UseAutonomousPrefix=</varname></term>
-           <listitem>
-diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
-index f58edb8f3cae..fe1f1e0333cf 100644
---- a/src/network/networkd-ndisc.c
-+++ b/src/network/networkd-ndisc.c
-@@ -536,9 +536,9 @@ static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
- static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
-         _cleanup_(route_freep) Route *route = NULL;
-         struct in6_addr gateway;
--        uint16_t lifetime;
-+        uint32_t table, mtu = 0;
-         unsigned preference;
--        uint32_t table, mtu;
-+        uint16_t lifetime;
-         usec_t time_now;
-         int r;
- 
-@@ -575,11 +575,11 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
-         if (r < 0)
-                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
- 
--        r = sd_ndisc_router_get_mtu(rt, &mtu);
--        if (r == -ENODATA)
--                mtu = 0;
--        else if (r < 0)
--                return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
-+        if (link->network->ipv6_accept_ra_use_mtu) {
-+                r = sd_ndisc_router_get_mtu(rt, &mtu);
-+                if (r < 0 && r != -ENODATA)
-+                        return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
-+        }
- 
-         table = link_get_ipv6_accept_ra_route_table(link);
- 
-diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
-index aa4dc00e55bc..846e54aed759 100644
---- a/src/network/networkd-network-gperf.gperf
-+++ b/src/network/networkd-network-gperf.gperf
-@@ -256,6 +256,7 @@ IPv6AcceptRA.UseAutonomousPrefix,            config_parse_bool,
- IPv6AcceptRA.UseOnLinkPrefix,                config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
- IPv6AcceptRA.UseDNS,                         config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_dns)
- IPv6AcceptRA.UseDomains,                     config_parse_ipv6_accept_ra_use_domains,                  0,                             offsetof(Network, ipv6_accept_ra_use_domains)
-+IPv6AcceptRA.UseMTU,                         config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_mtu)
- IPv6AcceptRA.DHCPv6Client,                   config_parse_ipv6_accept_ra_start_dhcp6_client,           0,                             offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
- IPv6AcceptRA.RouteTable,                     config_parse_section_route_table,                         0,                             0
- IPv6AcceptRA.RouteMetric,                    config_parse_dhcp_route_metric,                           0,                             0
-diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
-index bb09ba9e8933..1928db537e0c 100644
---- a/src/network/networkd-network.c
-+++ b/src/network/networkd-network.c
-@@ -400,15 +400,16 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
-                 .ipv4_accept_local = -1,
-                 .ipv4_route_localnet = -1,
-                 .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
--                .ipv6_accept_ra = -1,
-                 .ipv6_dad_transmits = -1,
-                 .ipv6_hop_limit = -1,
-                 .ipv6_proxy_ndp = -1,
-                 .proxy_arp = -1,
- 
-+                .ipv6_accept_ra = -1,
-                 .ipv6_accept_ra_use_dns = true,
-                 .ipv6_accept_ra_use_autonomous_prefix = true,
-                 .ipv6_accept_ra_use_onlink_prefix = true,
-+                .ipv6_accept_ra_use_mtu = true,
-                 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
-                 .ipv6_accept_ra_route_metric = DHCP_ROUTE_METRIC,
-                 .ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
-diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
-index 815bcf5023fc..95c86e723040 100644
---- a/src/network/networkd-network.h
-+++ b/src/network/networkd-network.h
-@@ -301,6 +301,7 @@ struct Network {
-         bool ipv6_accept_ra_use_dns;
-         bool ipv6_accept_ra_use_autonomous_prefix;
-         bool ipv6_accept_ra_use_onlink_prefix;
-+        bool ipv6_accept_ra_use_mtu;
-         bool active_slave;
-         bool primary_slave;
-         DHCPUseDomains ipv6_accept_ra_use_domains;
-diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
-index 8fe4ced35154..a3711cb77d9c 100644
---- a/test/fuzz/fuzz-network-parser/directives.network
-+++ b/test/fuzz/fuzz-network-parser/directives.network
-@@ -342,6 +342,7 @@ Label=
- Prefix=
- [IPv6AcceptRA]
- UseDomains=
-+UseMTU=
- RouteTable=
- RouteMetric=
- UseDNS=
diff --git a/20541.patch b/20541.patch
deleted file mode 100644
index e41e3b1..0000000
--- a/20541.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From 72328a5977d240d33b78b24e7a6b65b1074000b9 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Thu, 26 Aug 2021 03:31:05 +0900
-Subject: [PATCH 1/2] ethtool: move function
-
-I'd like to locate all conf parsers at end of file.
----
- src/shared/ethtool-util.c | 250 +++++++++++++++++++-------------------
- 1 file changed, 125 insertions(+), 125 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index c47d819f0596..af3b917c75cb 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -932,6 +932,131 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
-         return 0;
- }
- 
-+int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce) {
-+        struct ethtool_coalesce ecmd = {
-+                .cmd = ETHTOOL_GCOALESCE,
-+        };
-+        struct ifreq ifr = {
-+                .ifr_data = (void*) &ecmd,
-+        };
-+        bool need_update = false;
-+        int r;
-+
-+        assert(ethtool_fd);
-+        assert(ifname);
-+        assert(coalesce);
-+
-+        if (coalesce->use_adaptive_rx_coalesce < 0 &&
-+            coalesce->use_adaptive_tx_coalesce < 0 &&
-+            !coalesce->rx_coalesce_usecs.set &&
-+            !coalesce->rx_max_coalesced_frames.set &&
-+            !coalesce->rx_coalesce_usecs_irq.set &&
-+            !coalesce->rx_max_coalesced_frames_irq.set &&
-+            !coalesce->tx_coalesce_usecs.set &&
-+            !coalesce->tx_max_coalesced_frames.set &&
-+            !coalesce->tx_coalesce_usecs_irq.set &&
-+            !coalesce->tx_max_coalesced_frames_irq.set &&
-+            !coalesce->stats_block_coalesce_usecs.set &&
-+            !coalesce->pkt_rate_low.set &&
-+            !coalesce->rx_coalesce_usecs_low.set &&
-+            !coalesce->rx_max_coalesced_frames_low.set &&
-+            !coalesce->tx_coalesce_usecs_low.set &&
-+            !coalesce->tx_max_coalesced_frames_low.set &&
-+            !coalesce->pkt_rate_high.set &&
-+            !coalesce->rx_coalesce_usecs_high.set &&
-+            !coalesce->rx_max_coalesced_frames_high.set &&
-+            !coalesce->tx_coalesce_usecs_high.set &&
-+            !coalesce->tx_max_coalesced_frames_high.set &&
-+            !coalesce->rate_sample_interval.set)
-+                return 0;
-+
-+        r = ethtool_connect(ethtool_fd);
-+        if (r < 0)
-+                return r;
-+
-+        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+
-+        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-+        if (r < 0)
-+                return -errno;
-+
-+        if (coalesce->use_adaptive_rx_coalesce >= 0)
-+                UPDATE(ecmd.use_adaptive_rx_coalesce, (uint32_t) coalesce->use_adaptive_rx_coalesce, need_update);
-+
-+        if (coalesce->use_adaptive_tx_coalesce >= 0)
-+                UPDATE(ecmd.use_adaptive_tx_coalesce, (uint32_t) coalesce->use_adaptive_tx_coalesce, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs.set)
-+                UPDATE(ecmd.rx_coalesce_usecs, coalesce->rx_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames, coalesce->rx_max_coalesced_frames.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_irq.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_irq, coalesce->rx_coalesce_usecs_irq.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_irq.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_irq, coalesce->rx_max_coalesced_frames_irq.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs.set)
-+                UPDATE(ecmd.tx_coalesce_usecs, coalesce->tx_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames, coalesce->tx_max_coalesced_frames.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_irq.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_irq, coalesce->tx_coalesce_usecs_irq.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_irq.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_irq, coalesce->tx_max_coalesced_frames_irq.value, need_update);
-+
-+        if (coalesce->stats_block_coalesce_usecs.set)
-+                UPDATE(ecmd.stats_block_coalesce_usecs, coalesce->stats_block_coalesce_usecs.value, need_update);
-+
-+        if (coalesce->pkt_rate_low.set)
-+                UPDATE(ecmd.pkt_rate_low, coalesce->pkt_rate_low.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_low.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_low, coalesce->rx_coalesce_usecs_low.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_low.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_low, coalesce->rx_max_coalesced_frames_low.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_low.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_low, coalesce->tx_coalesce_usecs_low.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_low.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_low, coalesce->tx_max_coalesced_frames_low.value, need_update);
-+
-+        if (coalesce->pkt_rate_high.set)
-+                UPDATE(ecmd.pkt_rate_high, coalesce->pkt_rate_high.value, need_update);
-+
-+        if (coalesce->rx_coalesce_usecs_high.set)
-+                UPDATE(ecmd.rx_coalesce_usecs_high, coalesce->rx_coalesce_usecs_high.value, need_update);
-+
-+        if (coalesce->rx_max_coalesced_frames_high.set)
-+                UPDATE(ecmd.rx_max_coalesced_frames_high, coalesce->rx_max_coalesced_frames_high.value, need_update);
-+
-+        if (coalesce->tx_coalesce_usecs_high.set)
-+                UPDATE(ecmd.tx_coalesce_usecs_high, coalesce->tx_coalesce_usecs_high.value, need_update);
-+
-+        if (coalesce->tx_max_coalesced_frames_high.set)
-+                UPDATE(ecmd.tx_max_coalesced_frames_high, coalesce->tx_max_coalesced_frames_high.value, need_update);
-+
-+        if (coalesce->rate_sample_interval.set)
-+                UPDATE(ecmd.rate_sample_interval, DIV_ROUND_UP(coalesce->rate_sample_interval.value, USEC_PER_SEC), need_update);
-+
-+        if (!need_update)
-+                return 0;
-+
-+        ecmd.cmd = ETHTOOL_SCOALESCE;
-+        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-+        if (r < 0)
-+                return -errno;
-+
-+        return 0;
-+}
-+
- int config_parse_advertise(
-                 const char *unit,
-                 const char *filename,
-@@ -1182,128 +1307,3 @@ int config_parse_coalesce_sec(
- 
-         return 0;
- }
--
--int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce) {
--        struct ethtool_coalesce ecmd = {
--                .cmd = ETHTOOL_GCOALESCE,
--        };
--        struct ifreq ifr = {
--                .ifr_data = (void*) &ecmd,
--        };
--        bool need_update = false;
--        int r;
--
--        assert(ethtool_fd);
--        assert(ifname);
--        assert(coalesce);
--
--        if (coalesce->use_adaptive_rx_coalesce < 0 &&
--            coalesce->use_adaptive_tx_coalesce < 0 &&
--            !coalesce->rx_coalesce_usecs.set &&
--            !coalesce->rx_max_coalesced_frames.set &&
--            !coalesce->rx_coalesce_usecs_irq.set &&
--            !coalesce->rx_max_coalesced_frames_irq.set &&
--            !coalesce->tx_coalesce_usecs.set &&
--            !coalesce->tx_max_coalesced_frames.set &&
--            !coalesce->tx_coalesce_usecs_irq.set &&
--            !coalesce->tx_max_coalesced_frames_irq.set &&
--            !coalesce->stats_block_coalesce_usecs.set &&
--            !coalesce->pkt_rate_low.set &&
--            !coalesce->rx_coalesce_usecs_low.set &&
--            !coalesce->rx_max_coalesced_frames_low.set &&
--            !coalesce->tx_coalesce_usecs_low.set &&
--            !coalesce->tx_max_coalesced_frames_low.set &&
--            !coalesce->pkt_rate_high.set &&
--            !coalesce->rx_coalesce_usecs_high.set &&
--            !coalesce->rx_max_coalesced_frames_high.set &&
--            !coalesce->tx_coalesce_usecs_high.set &&
--            !coalesce->tx_max_coalesced_frames_high.set &&
--            !coalesce->rate_sample_interval.set)
--                return 0;
--
--        r = ethtool_connect(ethtool_fd);
--        if (r < 0)
--                return r;
--
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
--
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
--                return -errno;
--
--        if (coalesce->use_adaptive_rx_coalesce >= 0)
--                UPDATE(ecmd.use_adaptive_rx_coalesce, (uint32_t) coalesce->use_adaptive_rx_coalesce, need_update);
--
--        if (coalesce->use_adaptive_tx_coalesce >= 0)
--                UPDATE(ecmd.use_adaptive_tx_coalesce, (uint32_t) coalesce->use_adaptive_tx_coalesce, need_update);
--
--        if (coalesce->rx_coalesce_usecs.set)
--                UPDATE(ecmd.rx_coalesce_usecs, coalesce->rx_coalesce_usecs.value, need_update);
--
--        if (coalesce->rx_max_coalesced_frames.set)
--                UPDATE(ecmd.rx_max_coalesced_frames, coalesce->rx_max_coalesced_frames.value, need_update);
--
--        if (coalesce->rx_coalesce_usecs_irq.set)
--                UPDATE(ecmd.rx_coalesce_usecs_irq, coalesce->rx_coalesce_usecs_irq.value, need_update);
--
--        if (coalesce->rx_max_coalesced_frames_irq.set)
--                UPDATE(ecmd.rx_max_coalesced_frames_irq, coalesce->rx_max_coalesced_frames_irq.value, need_update);
--
--        if (coalesce->tx_coalesce_usecs.set)
--                UPDATE(ecmd.tx_coalesce_usecs, coalesce->tx_coalesce_usecs.value, need_update);
--
--        if (coalesce->tx_max_coalesced_frames.set)
--                UPDATE(ecmd.tx_max_coalesced_frames, coalesce->tx_max_coalesced_frames.value, need_update);
--
--        if (coalesce->tx_coalesce_usecs_irq.set)
--                UPDATE(ecmd.tx_coalesce_usecs_irq, coalesce->tx_coalesce_usecs_irq.value, need_update);
--
--        if (coalesce->tx_max_coalesced_frames_irq.set)
--                UPDATE(ecmd.tx_max_coalesced_frames_irq, coalesce->tx_max_coalesced_frames_irq.value, need_update);
--
--        if (coalesce->stats_block_coalesce_usecs.set)
--                UPDATE(ecmd.stats_block_coalesce_usecs, coalesce->stats_block_coalesce_usecs.value, need_update);
--
--        if (coalesce->pkt_rate_low.set)
--                UPDATE(ecmd.pkt_rate_low, coalesce->pkt_rate_low.value, need_update);
--
--        if (coalesce->rx_coalesce_usecs_low.set)
--                UPDATE(ecmd.rx_coalesce_usecs_low, coalesce->rx_coalesce_usecs_low.value, need_update);
--
--        if (coalesce->rx_max_coalesced_frames_low.set)
--                UPDATE(ecmd.rx_max_coalesced_frames_low, coalesce->rx_max_coalesced_frames_low.value, need_update);
--
--        if (coalesce->tx_coalesce_usecs_low.set)
--                UPDATE(ecmd.tx_coalesce_usecs_low, coalesce->tx_coalesce_usecs_low.value, need_update);
--
--        if (coalesce->tx_max_coalesced_frames_low.set)
--                UPDATE(ecmd.tx_max_coalesced_frames_low, coalesce->tx_max_coalesced_frames_low.value, need_update);
--
--        if (coalesce->pkt_rate_high.set)
--                UPDATE(ecmd.pkt_rate_high, coalesce->pkt_rate_high.value, need_update);
--
--        if (coalesce->rx_coalesce_usecs_high.set)
--                UPDATE(ecmd.rx_coalesce_usecs_high, coalesce->rx_coalesce_usecs_high.value, need_update);
--
--        if (coalesce->rx_max_coalesced_frames_high.set)
--                UPDATE(ecmd.rx_max_coalesced_frames_high, coalesce->rx_max_coalesced_frames_high.value, need_update);
--
--        if (coalesce->tx_coalesce_usecs_high.set)
--                UPDATE(ecmd.tx_coalesce_usecs_high, coalesce->tx_coalesce_usecs_high.value, need_update);
--
--        if (coalesce->tx_max_coalesced_frames_high.set)
--                UPDATE(ecmd.tx_max_coalesced_frames_high, coalesce->tx_max_coalesced_frames_high.value, need_update);
--
--        if (coalesce->rate_sample_interval.set)
--                UPDATE(ecmd.rate_sample_interval, DIV_ROUND_UP(coalesce->rate_sample_interval.value, USEC_PER_SEC), need_update);
--
--        if (!need_update)
--                return 0;
--
--        ecmd.cmd = ETHTOOL_SCOALESCE;
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
--                return -errno;
--
--        return 0;
--}
-
-From ee7512404b5de7c5ac36e09436379fada2ed84e7 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Thu, 26 Aug 2021 03:34:23 +0900
-Subject: [PATCH 2/2] udev/net: initialize coalesce tristate variables
-
-Otherwise, 99-default.link may introduce something like the
-following warnings:
-----
-Aug 26 03:23:59 systemd-udevd[519]: wlan0: Could not set coalesce settings, ignoring: Operation not supported
-Aug 26 03:24:00 systemd-udevd[547]: wlp59s0: Could not set coalesce settings, ignoring: Operation not supported
-----
-
-Follow-up for 6c35ea5ef0231d519ff24d43a57a72cebab6a121.
----
- src/udev/net/link-config.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
-index 69f651435034..4963ba2fae81 100644
---- a/src/udev/net/link-config.c
-+++ b/src/udev/net/link-config.c
-@@ -142,6 +142,8 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
-                 .tx_flow_control = -1,
-                 .autoneg_flow_control = -1,
-                 .txqueuelen = UINT32_MAX,
-+                .coalesce.use_adaptive_rx_coalesce = -1,
-+                .coalesce.use_adaptive_tx_coalesce = -1,
-         };
- 
-         for (i = 0; i < ELEMENTSOF(link->features); i++)
diff --git a/20676_cherrypicked.patch b/20676_cherrypicked.patch
deleted file mode 100644
index e97a589..0000000
--- a/20676_cherrypicked.patch
+++ /dev/null
@@ -1,336 +0,0 @@
-From 0b9f08931944c2e33c6ed012919157e429eb7be2 Mon Sep 17 00:00:00 2001
-From: Antony Deepak Thomas <antonydeepak@gmail.com>
-Date: Wed, 29 Sep 2021 12:47:49 +0900
-Subject: [PATCH 1/4] fileio: introduce read_virtual_file_fd()
-
----
- src/basic/fileio.c | 24 ++++++++++++++++--------
- src/basic/fileio.h |  1 +
- 2 files changed, 17 insertions(+), 8 deletions(-)
-
-diff --git a/src/basic/fileio.c b/src/basic/fileio.c
-index 466c6321c7..4a0d060105 100644
---- a/src/basic/fileio.c
-+++ b/src/basic/fileio.c
-@@ -373,9 +373,8 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
-         return 1;
- }
- 
--int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) {
-+int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size) {
-         _cleanup_free_ char *buf = NULL;
--        _cleanup_close_ int fd = -1;
-         size_t n, size;
-         int n_retries;
-         bool truncated = false;
-@@ -393,10 +392,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
-          * contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on
-          * partial success, 1 if untruncated contents were read. */
- 
--        fd = open(filename, O_RDONLY|O_CLOEXEC);
--        if (fd < 0)
--                return -errno;
--
-+        assert(fd >= 0);
-         assert(max_size <= READ_VIRTUAL_BYTES_MAX || max_size == SIZE_MAX);
- 
-         /* Limit the number of attempts to read the number of bytes returned by fstat(). */
-@@ -432,8 +428,8 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
- 
-                         n_retries--;
-                 } else if (n_retries > 1) {
--                        /* Files in /proc are generally smaller than the page size so let's start with a page size
--                         * buffer from malloc and only use the max buffer on the final try. */
-+                        /* Files in /proc are generally smaller than the page size so let's start with
-+                         * a page size buffer from malloc and only use the max buffer on the final try. */
-                         size = MIN3(page_size() - 1, READ_VIRTUAL_BYTES_MAX, max_size);
-                         n_retries = 1;
-                 } else {
-@@ -517,6 +513,18 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
-         return !truncated;
- }
- 
-+int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) {
-+        _cleanup_close_ int fd = -1;
-+
-+        assert(filename);
-+
-+        fd = open(filename, O_RDONLY | O_NOCTTY | O_CLOEXEC);
-+        if (fd < 0)
-+                return -errno;
-+
-+        return read_virtual_file_fd(fd, max_size, ret_contents, ret_size);
-+}
-+
- int read_full_stream_full(
-                 FILE *f,
-                 const char *filename,
-diff --git a/src/basic/fileio.h b/src/basic/fileio.h
-index 9bd2037f5b..82330840bf 100644
---- a/src/basic/fileio.h
-+++ b/src/basic/fileio.h
-@@ -66,6 +66,7 @@ static inline int read_full_file(const char *filename, char **ret_contents, size
-         return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size);
- }
- 
-+int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size);
- int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size);
- static inline int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) {
-         return read_virtual_file(filename, SIZE_MAX, ret_contents, ret_size);
--- 
-2.31.1
-
-
-From bede594fa1ea4c32a886191b774134effcf71bef Mon Sep 17 00:00:00 2001
-From: Antony Deepak Thomas <antonydeepak@gmail.com>
-Date: Wed, 29 Sep 2021 12:57:30 +0900
-Subject: [PATCH 2/4] string-util: introduce streq_skip_trailing_chars()
-
----
- src/basic/string-util.c     | 16 ++++++++++++++++
- src/basic/string-util.h     |  2 ++
- src/test/test-string-util.c | 28 ++++++++++++++++++++++++++++
- 3 files changed, 46 insertions(+)
-
-diff --git a/src/basic/string-util.c b/src/basic/string-util.c
-index a645958d38..6ceaeaf9df 100644
---- a/src/basic/string-util.c
-+++ b/src/basic/string-util.c
-@@ -1146,3 +1146,19 @@ int string_contains_word_strv(const char *string, const char *separators, char *
-                 *ret_word = found;
-         return !!found;
- }
-+
-+bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok) {
-+        if (!s1 && !s2)
-+                return true;
-+        if (!s1 || !s2)
-+                return false;
-+
-+        if (!ok)
-+                ok = WHITESPACE;
-+
-+        for (; *s1 && *s2; s1++, s2++)
-+                if (*s1 != *s2)
-+                        break;
-+
-+        return in_charset(s1, ok) && in_charset(s2, ok);
-+}
-diff --git a/src/basic/string-util.h b/src/basic/string-util.h
-index 9155e50ba8..0bf215827e 100644
---- a/src/basic/string-util.h
-+++ b/src/basic/string-util.h
-@@ -242,3 +242,5 @@ int string_contains_word_strv(const char *string, const char *separators, char *
- static inline int string_contains_word(const char *string, const char *separators, const char *word) {
-         return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL);
- }
-+
-+bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok);
-diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
-index 4d9d0260c9..9a9c974332 100644
---- a/src/test/test-string-util.c
-+++ b/src/test/test-string-util.c
-@@ -1000,6 +1000,33 @@ static void test_strextendf(void) {
-         assert_se(streq(p, "<77>,<99>,<                                                                              88>,<00001234>"));
- }
- 
-+static void test_streq_skip_trailing_chars(void) {
-+        log_info("/* %s */", __func__);
-+
-+        /* NULL is WHITESPACE by default*/
-+        assert_se(streq_skip_trailing_chars("foo bar", "foo bar", NULL));
-+        assert_se(streq_skip_trailing_chars("foo", "foo", NULL));
-+        assert_se(streq_skip_trailing_chars("foo bar      ", "foo bar", NULL));
-+        assert_se(streq_skip_trailing_chars("foo bar", "foo bar\t\t", NULL));
-+        assert_se(streq_skip_trailing_chars("foo bar  ", "foo bar\t\t", NULL));
-+        assert_se(streq_skip_trailing_chars("foo\nbar", "foo\nbar", NULL));
-+        assert_se(streq_skip_trailing_chars("\t\tfoo bar", "\t\tfoo bar", NULL));
-+        assert_se(streq_skip_trailing_chars(" foo bar\t", " foo bar\n", NULL));
-+
-+        assert_se(!streq_skip_trailing_chars("foobar", "foo bar", NULL));
-+        assert_se(!streq_skip_trailing_chars("foo\nbar", "foo\tbar", NULL));
-+        assert_se(!streq_skip_trailing_chars("\t\nfoo bar", "\t foo bar", NULL));
-+
-+        assert_se(streq_skip_trailing_chars("foo bar      ", "foo bar", WHITESPACE));
-+        assert_se(!streq_skip_trailing_chars("foo bar      ", "foo bar", NEWLINE));
-+
-+        assert_se(streq_skip_trailing_chars(NULL, NULL, NULL));
-+        assert_se(streq_skip_trailing_chars("", "", NULL));
-+        assert_se(!streq_skip_trailing_chars(NULL, "foo bar", NULL));
-+        assert_se(!streq_skip_trailing_chars("foo", NULL, NULL));
-+        assert_se(!streq_skip_trailing_chars("", "f", NULL));
-+}
-+
- int main(int argc, char *argv[]) {
-         test_setup_logging(LOG_DEBUG);
- 
-@@ -1039,6 +1066,7 @@ int main(int argc, char *argv[]) {
-         test_string_contains_word();
-         test_strverscmp_improved();
-         test_strextendf();
-+        test_streq_skip_trailing_chars();
- 
-         return 0;
- }
--- 
-2.31.1
-
-
-From a2552e17829d0090db3ff5f2e6f2d772d0fca3e9 Mon Sep 17 00:00:00 2001
-From: Antony Deepak Thomas <antonydeepak@gmail.com>
-Date: Wed, 29 Sep 2021 13:06:25 +0900
-Subject: [PATCH 3/4] fileio: introduce new mode to suppress writing the same
- value
-
----
- src/basic/fileio.c | 29 +++++++++++++++++++++++++++--
- src/basic/fileio.h | 23 ++++++++++++-----------
- 2 files changed, 39 insertions(+), 13 deletions(-)
-
-diff --git a/src/basic/fileio.c b/src/basic/fileio.c
-index 4a0d060105..729789ce47 100644
---- a/src/basic/fileio.c
-+++ b/src/basic/fileio.c
-@@ -146,6 +146,30 @@ int write_string_stream_ts(
-                         return -EBADF;
-         }
- 
-+        if (flags & WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) {
-+                _cleanup_free_ char *t = NULL;
-+
-+                /* If value to be written is same as that of the existing value, then suppress the write. */
-+
-+                if (fd < 0) {
-+                        fd = fileno(f);
-+                        if (fd < 0)
-+                                return -EBADF;
-+                }
-+
-+                /* Read an additional byte to detect cases where the prefix matches but the rest
-+                 * doesn't. Also, 0 returned by read_virtual_file_fd() means the read was truncated and
-+                 * it won't be equal to the new value. */
-+                if (read_virtual_file_fd(fd, strlen(line)+1, &t, NULL) > 0 &&
-+                    streq_skip_trailing_chars(line, t, NEWLINE)) {
-+                        log_debug("No change in value '%s', supressing write", line);
-+                        return 0;
-+                }
-+
-+                if (lseek(fd, 0, SEEK_SET) < 0)
-+                        return -errno;
-+        }
-+
-         needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
- 
-         if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
-@@ -261,10 +285,11 @@ int write_string_file_ts(
-                 assert(!ts);
- 
-         /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
--        fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY |
-+        fd = open(fn, O_CLOEXEC|O_NOCTTY |
-                   (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
-                   (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
--                  (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0),
-+                  (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
-+                  (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
-                   (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666));
-         if (fd < 0) {
-                 r = -errno;
-diff --git a/src/basic/fileio.h b/src/basic/fileio.h
-index 82330840bf..a72b2f3881 100644
---- a/src/basic/fileio.h
-+++ b/src/basic/fileio.h
-@@ -15,17 +15,18 @@
- #define LONG_LINE_MAX (1U*1024U*1024U)
- 
- typedef enum {
--        WRITE_STRING_FILE_CREATE                = 1 << 0,
--        WRITE_STRING_FILE_TRUNCATE              = 1 << 1,
--        WRITE_STRING_FILE_ATOMIC                = 1 << 2,
--        WRITE_STRING_FILE_AVOID_NEWLINE         = 1 << 3,
--        WRITE_STRING_FILE_VERIFY_ON_FAILURE     = 1 << 4,
--        WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE = 1 << 5,
--        WRITE_STRING_FILE_SYNC                  = 1 << 6,
--        WRITE_STRING_FILE_DISABLE_BUFFER        = 1 << 7,
--        WRITE_STRING_FILE_NOFOLLOW              = 1 << 8,
--        WRITE_STRING_FILE_MKDIR_0755            = 1 << 9,
--        WRITE_STRING_FILE_MODE_0600             = 1 << 10,
-+        WRITE_STRING_FILE_CREATE                     = 1 << 0,
-+        WRITE_STRING_FILE_TRUNCATE                   = 1 << 1,
-+        WRITE_STRING_FILE_ATOMIC                     = 1 << 2,
-+        WRITE_STRING_FILE_AVOID_NEWLINE              = 1 << 3,
-+        WRITE_STRING_FILE_VERIFY_ON_FAILURE          = 1 << 4,
-+        WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE      = 1 << 5,
-+        WRITE_STRING_FILE_SYNC                       = 1 << 6,
-+        WRITE_STRING_FILE_DISABLE_BUFFER             = 1 << 7,
-+        WRITE_STRING_FILE_NOFOLLOW                   = 1 << 8,
-+        WRITE_STRING_FILE_MKDIR_0755                 = 1 << 9,
-+        WRITE_STRING_FILE_MODE_0600                  = 1 << 10,
-+        WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 11,
- 
-         /* 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()
--- 
-2.31.1
-
-
-From 41d86b627331f432454280714dd5b17d255367ba Mon Sep 17 00:00:00 2001
-From: Antony Deepak Thomas <antonydeepak@gmail.com>
-Date: Wed, 29 Sep 2021 13:07:42 +0900
-Subject: [PATCH 4/4] sysctl-util: minimize side-effects when running
- `systemd-sysctl`
-
-Currently `systemd-sysctl` binary is used in `systemd-sysctl.service`
-which is mostly configured as `oneshot`. There are situations where one
-would like to use systemd to maintain Sysctl configurations on a host,
-using a configuration managers such as Chef or Puppet, by apply
-configurations every X duration.
-The problem with using `systemd-sysctl` is that it writes all the Sysctl
-settings, even if the values for those settings have not changed. From
-experience, we have observed that some Sysctl settings cause actions in
-the kernel upon writing(like dropping caches) which in turn cause
-undesired side effects.
-This patch tries to minimize such side effects by comparing values
-before writing.
----
- src/basic/sysctl-util.c | 19 +++++--------------
- 1 file changed, 5 insertions(+), 14 deletions(-)
-
-diff --git a/src/basic/sysctl-util.c b/src/basic/sysctl-util.c
-index 8913e6ff85..4da3eaf5f7 100644
---- a/src/basic/sysctl-util.c
-+++ b/src/basic/sysctl-util.c
-@@ -44,25 +44,16 @@ char *sysctl_normalize(char *s) {
- 
- int sysctl_write(const char *property, const char *value) {
-         char *p;
--        _cleanup_close_ int fd = -1;
--
-         assert(property);
-         assert(value);
--
--        log_debug("Setting '%s' to '%.*s'.", property, (int) strcspn(value, NEWLINE), value);
--
-         p = strjoina("/proc/sys/", property);
--        fd = open(p, O_WRONLY|O_CLOEXEC);
--        if (fd < 0)
--                return -errno;
-+        path_simplify(p);
-+        if (!path_is_normalized(p))
-+                return -EINVAL;
- 
--        if (!endswith(value, "\n"))
--                value = strjoina(value, "\n");
--
--        if (write(fd, value, strlen(value)) < 0)
--                return -errno;
-+        log_debug("Setting '%s' to '%s'", p, value);
- 
--        return 0;
-+        return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL);
- }
- 
- int sysctl_writef(const char *property, const char *format, ...) {
--- 
-2.31.1
-
diff --git a/20695.patch b/20695.patch
deleted file mode 100644
index f7ac0bd..0000000
--- a/20695.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 67cd626399b0d02882ee00716c8bd31ba764c862 Mon Sep 17 00:00:00 2001
-From: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Date: Fri, 10 Sep 2021 09:51:36 +1200
-Subject: [PATCH] basic/linux: Sync if_arp.h with Linux 5.14
-
-ARPHRD_MCTP was added in 5.14. Sync if_arp.h to pick up the definition
-
-Fixes #20694
----
- src/basic/linux/if_arp.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/basic/linux/if_arp.h b/src/basic/linux/if_arp.h
-index c3cc5a9e5eaf..4783af9fe520 100644
---- a/src/basic/linux/if_arp.h
-+++ b/src/basic/linux/if_arp.h
-@@ -54,6 +54,7 @@
- #define ARPHRD_X25	271		/* CCITT X.25			*/
- #define ARPHRD_HWX25	272		/* Boards with X.25 in firmware	*/
- #define ARPHRD_CAN	280		/* Controller Area Network      */
-+#define ARPHRD_MCTP	290
- #define ARPHRD_PPP	512
- #define ARPHRD_CISCO	513		/* Cisco HDLC	 		*/
- #define ARPHRD_HDLC	ARPHRD_CISCO
diff --git a/20729.patch b/20729.patch
deleted file mode 100644
index 82904e5..0000000
--- a/20729.patch
+++ /dev/null
@@ -1,927 +0,0 @@
-From 6d9a72f3b9b4d00ec80051503e5e3d4d7cd46c05 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 15 Sep 2021 01:28:29 +0900
-Subject: [PATCH 1/5] ethtool-util: use sizeof()
-
----
- src/shared/ethtool-util.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index af3b917c75cb..d1f5eac63334 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -214,7 +214,7 @@ int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret) {
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -254,7 +254,7 @@ int ethtool_get_link_info(
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -303,7 +303,7 @@ int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct et
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -362,7 +362,7 @@ int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts) {
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -405,7 +405,7 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -538,7 +538,7 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = get_stringset(*ethtool_fd, &ifr, ETH_SS_FEATURES, &strings);
-         if (r < 0)
-@@ -787,7 +787,7 @@ int ethtool_set_glinksettings(
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = get_glinksettings(*fd, &ifr, &u);
-         if (r < 0) {
-@@ -857,7 +857,7 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -906,7 +906,7 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-@@ -974,7 +974,7 @@ int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
-         if (r < 0)
-
-From 4253dab576b3ff17887c3e0d97380aab2aa29d82 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 15 Sep 2021 01:41:15 +0900
-Subject: [PATCH 2/5] ethtool-util: shorten code a bit
-
-Also fixes a error code in debugging log.
----
- src/shared/ethtool-util.c | 70 ++++++++++++---------------------------
- 1 file changed, 22 insertions(+), 48 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index d1f5eac63334..ac21ef0f61a8 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -216,8 +216,7 @@ int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret) {
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (isempty(ecmd.driver))
-@@ -256,8 +255,7 @@ int ethtool_get_link_info(
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (ret_autonegotiation)
-@@ -305,8 +303,7 @@ int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct et
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (epaddr.addr.size != 6)
-@@ -364,8 +361,7 @@ int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts) {
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         UPDATE(ecmd.wolopts, wolopts, need_update);
-@@ -374,8 +370,7 @@ int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts) {
-                 return 0;
- 
-         ecmd.cmd = ETHTOOL_SWOL;
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -407,8 +402,7 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (ring->rx.set)
-@@ -427,8 +421,7 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-                 return 0;
- 
-         ecmd.cmd = ETHTOOL_SRINGPARAM;
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -446,7 +439,6 @@ static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, st
-                 },
-         };
-         unsigned len;
--        int r;
- 
-         assert(ethtool_fd >= 0);
-         assert(ifr);
-@@ -454,8 +446,7 @@ static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, st
- 
-         ifr->ifr_data = (void *) &buffer.info;
- 
--        r = ioctl(ethtool_fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(ethtool_fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         if (!buffer.info.sset_mask)
-@@ -478,8 +469,7 @@ static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, st
- 
-         ifr->ifr_data = (void *) strings;
- 
--        r = ioctl(ethtool_fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(ethtool_fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         *ret = TAKE_PTR(strings);
-@@ -559,9 +549,8 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
- 
-         ifr.ifr_data = (void *) sfeatures;
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
--                return log_debug_errno(r, "ethtool: could not set ethtool features for %s", ifname);
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-+                return log_debug_errno(errno, "ethtool: could not set ethtool features for %s", ifname);
- 
-         return 0;
- }
-@@ -575,7 +564,6 @@ static int get_glinksettings(int fd, struct ifreq *ifr, struct ethtool_link_uset
-         };
-         struct ethtool_link_usettings *u;
-         unsigned offset;
--        int r;
- 
-         assert(fd >= 0);
-         assert(ifr);
-@@ -591,8 +579,7 @@ static int get_glinksettings(int fd, struct ifreq *ifr, struct ethtool_link_uset
- 
-         ifr->ifr_data = (void *) &ecmd;
- 
--        r = ioctl(fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
-@@ -602,8 +589,7 @@ static int get_glinksettings(int fd, struct ifreq *ifr, struct ethtool_link_uset
- 
-         ifr->ifr_data = (void *) &ecmd;
- 
--        r = ioctl(fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         if (ecmd.req.link_mode_masks_nwords <= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
-@@ -636,7 +622,6 @@ static int get_gset(int fd, struct ifreq *ifr, struct ethtool_link_usettings **r
-         struct ethtool_cmd ecmd = {
-                 .cmd = ETHTOOL_GSET,
-         };
--        int r;
- 
-         assert(fd >= 0);
-         assert(ifr);
-@@ -644,8 +629,7 @@ static int get_gset(int fd, struct ifreq *ifr, struct ethtool_link_usettings **r
- 
-         ifr->ifr_data = (void *) &ecmd;
- 
--        r = ioctl(fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         e = new(struct ethtool_link_usettings, 1);
-@@ -678,7 +662,6 @@ static int set_slinksettings(int fd, struct ifreq *ifr, const struct ethtool_lin
-                 __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
-         } ecmd = {};
-         unsigned offset;
--        int r;
- 
-         assert(fd >= 0);
-         assert(ifr);
-@@ -700,8 +683,7 @@ static int set_slinksettings(int fd, struct ifreq *ifr, const struct ethtool_lin
- 
-         ifr->ifr_data = (void *) &ecmd;
- 
--        r = ioctl(fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -711,7 +693,6 @@ static int set_sset(int fd, struct ifreq *ifr, const struct ethtool_link_usettin
-         struct ethtool_cmd ecmd = {
-                 .cmd = ETHTOOL_SSET,
-         };
--        int r;
- 
-         assert(fd >= 0);
-         assert(ifr);
-@@ -736,8 +717,7 @@ static int set_sset(int fd, struct ifreq *ifr, const struct ethtool_link_usettin
- 
-         ifr->ifr_data = (void *) &ecmd;
- 
--        r = ioctl(fd, SIOCETHTOOL, ifr);
--        if (r < 0)
-+        if (ioctl(fd, SIOCETHTOOL, ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -859,8 +839,7 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (channels->rx.set)
-@@ -879,8 +858,7 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
-                 return 0;
- 
-         ecmd.cmd = ETHTOOL_SCHANNELS;
--        r = ioctl(*fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -908,8 +886,7 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (rx >= 0)
-@@ -925,8 +902,7 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
-                 return 0;
- 
-         ecmd.cmd = ETHTOOL_SPAUSEPARAM;
--        r = ioctl(*fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         return 0;
-@@ -976,8 +952,7 @@ int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const
- 
-         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         if (coalesce->use_adaptive_rx_coalesce >= 0)
-@@ -1050,8 +1025,7 @@ int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const
-                 return 0;
- 
-         ecmd.cmd = ETHTOOL_SCOALESCE;
--        r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
--        if (r < 0)
-+        if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         return 0;
-
-From 008d3a370ccdea13290ab9277b32cc582b886b17 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Tue, 14 Sep 2021 17:42:52 +0900
-Subject: [PATCH 3/5] ethtool: do not set unavailable or never_changed bits
-
----
- src/shared/ethtool-util.c | 138 ++++++++++++++++++++++++++------------
- 1 file changed, 96 insertions(+), 42 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index ac21ef0f61a8..59b1bd86f085 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -427,30 +427,31 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
-         return 0;
- }
- 
--static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **ret) {
-+static int get_stringset(int ethtool_fd, const char *ifname, enum ethtool_stringset stringset_id, struct ethtool_gstrings **ret) {
-         _cleanup_free_ struct ethtool_gstrings *strings = NULL;
-         struct {
-                 struct ethtool_sset_info info;
-                 uint32_t space;
-         } buffer = {
--                .info = {
--                        .cmd = ETHTOOL_GSSET_INFO,
--                        .sset_mask = UINT64_C(1) << stringset_id,
--                },
-+                .info.cmd = ETHTOOL_GSSET_INFO,
-+                .info.sset_mask = UINT64_C(1) << stringset_id,
-         };
--        unsigned len;
-+        struct ifreq ifr = {
-+                .ifr_data = (void*) &buffer,
-+        };
-+        uint32_t len;
- 
-         assert(ethtool_fd >= 0);
--        assert(ifr);
-+        assert(ifname);
-         assert(ret);
- 
--        ifr->ifr_data = (void *) &buffer.info;
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
--        if (ioctl(ethtool_fd, SIOCETHTOOL, ifr) < 0)
-+        if (ioctl(ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
--        if (!buffer.info.sset_mask)
--                return -EINVAL;
-+        if (buffer.info.sset_mask == 0)
-+                return -EOPNOTSUPP;
- 
- #pragma GCC diagnostic push
- #if HAVE_ZERO_LENGTH_BOUNDS
-@@ -458,8 +459,10 @@ static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, st
- #endif
-         len = buffer.info.data[0];
- #pragma GCC diagnostic pop
-+        if (len == 0)
-+                return -EOPNOTSUPP;
- 
--        strings = malloc0(sizeof(struct ethtool_gstrings) + len * ETH_GSTRING_LEN);
-+        strings = malloc0(offsetof(struct ethtool_gstrings, data) + len * ETH_GSTRING_LEN);
-         if (!strings)
-                 return -ENOMEM;
- 
-@@ -467,47 +470,92 @@ static int get_stringset(int ethtool_fd, struct ifreq *ifr, int stringset_id, st
-         strings->string_set = stringset_id;
-         strings->len = len;
- 
--        ifr->ifr_data = (void *) strings;
-+        ifr.ifr_data = (void*) strings;
- 
--        if (ioctl(ethtool_fd, SIOCETHTOOL, ifr) < 0)
-+        if (ioctl(ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return -errno;
- 
-         *ret = TAKE_PTR(strings);
-+        return 0;
-+}
-+
-+static int get_features(int ethtool_fd, const char *ifname, uint32_t n_features, struct ethtool_gfeatures **ret) {
-+        _cleanup_free_ struct ethtool_gfeatures *gfeatures = NULL;
-+        struct ifreq ifr;
-+
-+        assert(ethtool_fd >= 0);
-+        assert(ifname);
-+        assert(ret);
-+        assert(n_features > 0);
-+
-+        gfeatures = malloc0(offsetof(struct ethtool_gfeatures, features) +
-+                            DIV_ROUND_UP(n_features, 32U) * sizeof(gfeatures->features[0]));
-+        if (!gfeatures)
-+                return -ENOMEM;
-+
-+        gfeatures->cmd = ETHTOOL_GFEATURES;
-+        gfeatures->size = DIV_ROUND_UP(n_features, 32U);
-+
-+        ifr = (struct ifreq) {
-+                .ifr_data = (void*) gfeatures,
-+        };
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
-+
-+        if (ioctl(ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-+                return -errno;
- 
-+        *ret = TAKE_PTR(gfeatures);
-         return 0;
- }
- 
- static int set_features_bit(
-                 const struct ethtool_gstrings *strings,
-+                const struct ethtool_gfeatures *gfeatures,
-+                struct ethtool_sfeatures *sfeatures,
-                 const char *feature,
--                bool flag,
--                struct ethtool_sfeatures *sfeatures) {
-+                int flag) {
-+
-         bool found = false;
-+        int r = -ENODATA;
- 
-         assert(strings);
--        assert(feature);
-+        assert(gfeatures);
-         assert(sfeatures);
-+        assert(feature);
-+
-+        if (flag < 0)
-+                return 0;
-+
-+        for (uint32_t i = 0; i < strings->len; i++) {
-+                uint32_t block, mask;
- 
--        for (size_t i = 0; i < strings->len; i++)
--                if (streq((char *) &strings->data[i * ETH_GSTRING_LEN], feature) ||
--                    (endswith(feature, "-") && startswith((char *) &strings->data[i * ETH_GSTRING_LEN], feature))) {
--                        size_t block, bit;
-+                if (!strneq((const char*) &strings->data[i * ETH_GSTRING_LEN], feature, ETH_GSTRING_LEN) &&
-+                    !(endswith(feature, "-") && startswith((const char*) &strings->data[i * ETH_GSTRING_LEN], feature)))
-+                        continue;
- 
--                        block = i / 32;
--                        bit = i % 32;
-+                block = i / 32;
-+                mask = UINT32_C(1) << (i % 32);
- 
--                        sfeatures->features[block].valid |= 1 << bit;
--                        SET_FLAG(sfeatures->features[block].requested, 1 << bit, flag);
--                        found = true;
-+                if (!FLAGS_SET(gfeatures->features[block].available, mask) ||
-+                    FLAGS_SET(gfeatures->features[block].never_changed, mask)) {
-+                        r = -EOPNOTSUPP;
-+                        continue;
-                 }
- 
--        return found ? 0 : -ENODATA;
-+                sfeatures->features[block].valid |= mask;
-+                SET_FLAG(sfeatures->features[block].requested, mask, flag);
-+
-+                found = true;
-+        }
-+
-+        return found ? 0 : r;
- }
- 
- int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features[static _NET_DEV_FEAT_MAX]) {
-         _cleanup_free_ struct ethtool_gstrings *strings = NULL;
--        struct ethtool_sfeatures *sfeatures;
--        struct ifreq ifr = {};
-+        _cleanup_free_ struct ethtool_gfeatures *gfeatures = NULL;
-+        _cleanup_free_ struct ethtool_sfeatures *sfeatures = NULL;
-+        struct ifreq ifr;
-         bool have = false;
-         int r;
- 
-@@ -528,26 +576,32 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
-         if (r < 0)
-                 return r;
- 
--        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
-+        r = get_stringset(*ethtool_fd, ifname, ETH_SS_FEATURES, &strings);
-+        if (r < 0)
-+                return log_debug_errno(r, "ethtool: could not get ethtool feature strings: %m");
- 
--        r = get_stringset(*ethtool_fd, &ifr, ETH_SS_FEATURES, &strings);
-+        r = get_features(*ethtool_fd, ifname, strings->len, &gfeatures);
-         if (r < 0)
--                return log_debug_errno(r, "ethtool: could not get ethtool features for %s", ifname);
-+                return log_debug_errno(r, "ethtool: could not get ethtool features for %s: %m", ifname);
-+
-+        sfeatures = malloc0(offsetof(struct ethtool_sfeatures, features) +
-+                            DIV_ROUND_UP(strings->len, 32U) * sizeof(sfeatures->features[0]));
-+        if (!sfeatures)
-+                return log_oom_debug();
- 
--        sfeatures = alloca0(sizeof(struct ethtool_sfeatures) + DIV_ROUND_UP(strings->len, 32U) * sizeof(sfeatures->features[0]));
-         sfeatures->cmd = ETHTOOL_SFEATURES;
-         sfeatures->size = DIV_ROUND_UP(strings->len, 32U);
- 
--        for (size_t i = 0; i < _NET_DEV_FEAT_MAX; i++)
--                if (features[i] >= 0) {
--                        r = set_features_bit(strings, netdev_feature_table[i], features[i], sfeatures);
--                        if (r < 0) {
--                                log_debug_errno(r, "ethtool: could not find feature, ignoring: %s", netdev_feature_table[i]);
--                                continue;
--                        }
--                }
-+        for (size_t i = 0; i < _NET_DEV_FEAT_MAX; i++) {
-+                r = set_features_bit(strings, gfeatures, sfeatures, netdev_feature_table[i], features[i]);
-+                if (r < 0)
-+                        log_debug_errno(r, "ethtool: could not set feature %s for %s, ignoring: %m", netdev_feature_table[i], ifname);
-+        }
- 
--        ifr.ifr_data = (void *) sfeatures;
-+        ifr = (struct ifreq) {
-+                .ifr_data = (void*) sfeatures,
-+        };
-+        strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
- 
-         if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
-                 return log_debug_errno(errno, "ethtool: could not set ethtool features for %s", ifname);
-
-From 7a4f203547c62cdc7611f38d97058b530570048f Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 15 Sep 2021 01:48:59 +0900
-Subject: [PATCH 4/5] ethtool-util: apply tx-checksum-* features at last
-
-NET_DEV_FEAT_TX matches multiple features. In the next commit, all
-features whose strings start with "tx-checksum-" will be added.
-To make them take precedence over NET_DEV_FEAT_TX, it will be applied
-only when each explicit feature is not applied.
----
- src/shared/ethtool-util.c | 55 ++++++++++++++++++++++++++++++++++++---
- src/shared/ethtool-util.h |  4 ++-
- 2 files changed, 54 insertions(+), 5 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index 59b1bd86f085..e95ce1a20917 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -71,13 +71,14 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse P
- 
- static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
-         [NET_DEV_FEAT_RX]     = "rx-checksum",
--        [NET_DEV_FEAT_TX]     = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
-         [NET_DEV_FEAT_GSO]    = "tx-generic-segmentation",
-         [NET_DEV_FEAT_GRO]    = "rx-gro",
-         [NET_DEV_FEAT_GRO_HW] = "rx-gro-hw",
-         [NET_DEV_FEAT_LRO]    = "rx-lro",
-         [NET_DEV_FEAT_TSO]    = "tx-tcp-segmentation",
-         [NET_DEV_FEAT_TSO6]   = "tx-tcp6-segmentation",
-+
-+        [NET_DEV_FEAT_TX]     = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
- };
- 
- static const char* const ethtool_link_mode_bit_table[] = {
-@@ -515,6 +516,43 @@ static int set_features_bit(
-                 const char *feature,
-                 int flag) {
- 
-+        assert(strings);
-+        assert(gfeatures);
-+        assert(sfeatures);
-+        assert(feature);
-+
-+        if (flag < 0)
-+                return 0;
-+
-+        for (uint32_t i = 0; i < strings->len; i++) {
-+                uint32_t block, mask;
-+
-+                if (!strneq((const char*) &strings->data[i * ETH_GSTRING_LEN], feature, ETH_GSTRING_LEN))
-+                        continue;
-+
-+                block = i / 32;
-+                mask = UINT32_C(1) << (i % 32);
-+
-+                if (!FLAGS_SET(gfeatures->features[block].available, mask) ||
-+                    FLAGS_SET(gfeatures->features[block].never_changed, mask))
-+                        return -EOPNOTSUPP;
-+
-+                sfeatures->features[block].valid |= mask;
-+                SET_FLAG(sfeatures->features[block].requested, mask, flag);
-+
-+                return 0;
-+        }
-+
-+        return -ENODATA;
-+}
-+
-+static int set_features_multiple_bit(
-+                const struct ethtool_gstrings *strings,
-+                const struct ethtool_gfeatures *gfeatures,
-+                struct ethtool_sfeatures *sfeatures,
-+                const char *feature,
-+                int flag) {
-+
-         bool found = false;
-         int r = -ENODATA;
- 
-@@ -529,8 +567,7 @@ static int set_features_bit(
-         for (uint32_t i = 0; i < strings->len; i++) {
-                 uint32_t block, mask;
- 
--                if (!strneq((const char*) &strings->data[i * ETH_GSTRING_LEN], feature, ETH_GSTRING_LEN) &&
--                    !(endswith(feature, "-") && startswith((const char*) &strings->data[i * ETH_GSTRING_LEN], feature)))
-+                if (!startswith((const char*) &strings->data[i * ETH_GSTRING_LEN], feature))
-                         continue;
- 
-                 block = i / 32;
-@@ -542,6 +579,10 @@ static int set_features_bit(
-                         continue;
-                 }
- 
-+                /* The flags is explicitly set by set_features_bit() */
-+                if (FLAGS_SET(sfeatures->features[block].valid, mask))
-+                        continue;
-+
-                 sfeatures->features[block].valid |= mask;
-                 SET_FLAG(sfeatures->features[block].requested, mask, flag);
- 
-@@ -592,12 +633,18 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
-         sfeatures->cmd = ETHTOOL_SFEATURES;
-         sfeatures->size = DIV_ROUND_UP(strings->len, 32U);
- 
--        for (size_t i = 0; i < _NET_DEV_FEAT_MAX; i++) {
-+        for (size_t i = 0; i < _NET_DEV_FEAT_SIMPLE_MAX; i++) {
-                 r = set_features_bit(strings, gfeatures, sfeatures, netdev_feature_table[i], features[i]);
-                 if (r < 0)
-                         log_debug_errno(r, "ethtool: could not set feature %s for %s, ignoring: %m", netdev_feature_table[i], ifname);
-         }
- 
-+        for (size_t i = _NET_DEV_FEAT_SIMPLE_MAX; i < _NET_DEV_FEAT_MAX; i++) {
-+                r = set_features_multiple_bit(strings, gfeatures, sfeatures, netdev_feature_table[i], features[i]);
-+                if (r < 0)
-+                        log_debug_errno(r, "ethtool: could not set feature %s for %s, ignoring: %m", netdev_feature_table[i], ifname);
-+        }
-+
-         ifr = (struct ifreq) {
-                 .ifr_data = (void*) sfeatures,
-         };
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index 6e180995055b..3f2252563304 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -20,13 +20,15 @@ typedef enum Duplex {
- 
- typedef enum NetDevFeature {
-         NET_DEV_FEAT_RX,
--        NET_DEV_FEAT_TX,
-         NET_DEV_FEAT_GSO,
-         NET_DEV_FEAT_GRO,
-         NET_DEV_FEAT_GRO_HW,
-         NET_DEV_FEAT_LRO,
-         NET_DEV_FEAT_TSO,
-         NET_DEV_FEAT_TSO6,
-+        _NET_DEV_FEAT_SIMPLE_MAX,
-+
-+        NET_DEV_FEAT_TX = _NET_DEV_FEAT_SIMPLE_MAX,
-         _NET_DEV_FEAT_MAX,
-         _NET_DEV_FEAT_INVALID = -EINVAL,
- } NetDevFeature;
-
-From 77bf5c31de1d01edd49ac6aa25cdbe7734a11a25 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Tue, 14 Sep 2021 22:12:42 +0900
-Subject: [PATCH 5/5] ethtool-util: add more network device features
-
-Then, we can easily add new settings to configure features in .link
-file.
----
- src/shared/ethtool-util.c            | 73 ++++++++++++++++++++++++----
- src/shared/ethtool-util.h            | 59 +++++++++++++++++++++-
- src/udev/net/link-config-gperf.gperf |  4 +-
- 3 files changed, 123 insertions(+), 13 deletions(-)
-
-diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c
-index e95ce1a20917..00060abff40f 100644
---- a/src/shared/ethtool-util.c
-+++ b/src/shared/ethtool-util.c
-@@ -70,15 +70,70 @@ DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
- DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
- 
- static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
--        [NET_DEV_FEAT_RX]     = "rx-checksum",
--        [NET_DEV_FEAT_GSO]    = "tx-generic-segmentation",
--        [NET_DEV_FEAT_GRO]    = "rx-gro",
--        [NET_DEV_FEAT_GRO_HW] = "rx-gro-hw",
--        [NET_DEV_FEAT_LRO]    = "rx-lro",
--        [NET_DEV_FEAT_TSO]    = "tx-tcp-segmentation",
--        [NET_DEV_FEAT_TSO6]   = "tx-tcp6-segmentation",
--
--        [NET_DEV_FEAT_TX]     = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
-+        [NET_DEV_FEAT_SG]                  = "tx-scatter-gather",
-+        [NET_DEV_FEAT_IP_CSUM]             = "tx-checksum-ipv4",
-+        [NET_DEV_FEAT_HW_CSUM]             = "tx-checksum-ip-generic",
-+        [NET_DEV_FEAT_IPV6_CSUM]           = "tx-checksum-ipv6",
-+        [NET_DEV_FEAT_HIGHDMA]             = "highdma",
-+        [NET_DEV_FEAT_FRAGLIST]            = "tx-scatter-gather-fraglist",
-+        [NET_DEV_FEAT_HW_VLAN_CTAG_TX]     = "tx-vlan-hw-insert",
-+        [NET_DEV_FEAT_HW_VLAN_CTAG_RX]     = "rx-vlan-hw-parse",
-+        [NET_DEV_FEAT_HW_VLAN_CTAG_FILTER] = "rx-vlan-filter",
-+        [NET_DEV_FEAT_HW_VLAN_STAG_TX]     = "tx-vlan-stag-hw-insert",
-+        [NET_DEV_FEAT_HW_VLAN_STAG_RX]     = "rx-vlan-stag-hw-parse",
-+        [NET_DEV_FEAT_HW_VLAN_STAG_FILTER] = "rx-vlan-stag-filter",
-+        [NET_DEV_FEAT_VLAN_CHALLENGED]     = "vlan-challenged",
-+        [NET_DEV_FEAT_GSO]                 = "tx-generic-segmentation",
-+        [NET_DEV_FEAT_LLTX]                = "tx-lockless",
-+        [NET_DEV_FEAT_NETNS_LOCAL]         = "netns-local",
-+        [NET_DEV_FEAT_GRO]                 = "rx-gro",
-+        [NET_DEV_FEAT_GRO_HW]              = "rx-gro-hw",
-+        [NET_DEV_FEAT_LRO]                 = "rx-lro",
-+        [NET_DEV_FEAT_TSO]                 = "tx-tcp-segmentation",
-+        [NET_DEV_FEAT_GSO_ROBUST]          = "tx-gso-robust",
-+        [NET_DEV_FEAT_TSO_ECN]             = "tx-tcp-ecn-segmentation",
-+        [NET_DEV_FEAT_TSO_MANGLEID]        = "tx-tcp-mangleid-segmentation",
-+        [NET_DEV_FEAT_TSO6]                = "tx-tcp6-segmentation",
-+        [NET_DEV_FEAT_FSO]                 = "tx-fcoe-segmentation",
-+        [NET_DEV_FEAT_GSO_GRE]             = "tx-gre-segmentation",
-+        [NET_DEV_FEAT_GSO_GRE_CSUM]        = "tx-gre-csum-segmentation",
-+        [NET_DEV_FEAT_GSO_IPXIP4]          = "tx-ipxip4-segmentation",
-+        [NET_DEV_FEAT_GSO_IPXIP6]          = "tx-ipxip6-segmentation",
-+        [NET_DEV_FEAT_GSO_UDP_TUNNEL]      = "tx-udp_tnl-segmentation",
-+        [NET_DEV_FEAT_GSO_UDP_TUNNEL_CSUM] = "tx-udp_tnl-csum-segmentation",
-+        [NET_DEV_FEAT_GSO_PARTIAL]         = "tx-gso-partial",
-+        [NET_DEV_FEAT_GSO_TUNNEL_REMCSUM]  = "tx-tunnel-remcsum-segmentation",
-+        [NET_DEV_FEAT_GSO_SCTP]            = "tx-sctp-segmentation",
-+        [NET_DEV_FEAT_GSO_ESP]             = "tx-esp-segmentation",
-+        [NET_DEV_FEAT_GSO_UDP_L4]          = "tx-udp-segmentation",
-+        [NET_DEV_FEAT_GSO_FRAGLIST]        = "tx-gso-list",
-+        [NET_DEV_FEAT_FCOE_CRC]            = "tx-checksum-fcoe-crc",
-+        [NET_DEV_FEAT_SCTP_CRC]            = "tx-checksum-sctp",
-+        [NET_DEV_FEAT_FCOE_MTU]            = "fcoe-mtu",
-+        [NET_DEV_FEAT_NTUPLE]              = "rx-ntuple-filter",
-+        [NET_DEV_FEAT_RXHASH]              = "rx-hashing",
-+        [NET_DEV_FEAT_RXCSUM]              = "rx-checksum",
-+        [NET_DEV_FEAT_NOCACHE_COPY]        = "tx-nocache-copy",
-+        [NET_DEV_FEAT_LOOPBACK]            = "loopback",
-+        [NET_DEV_FEAT_RXFCS]               = "rx-fcs",
-+        [NET_DEV_FEAT_RXALL]               = "rx-all",
-+        [NET_DEV_FEAT_HW_L2FW_DOFFLOAD]    = "l2-fwd-offload",
-+        [NET_DEV_FEAT_HW_TC]               = "hw-tc-offload",
-+        [NET_DEV_FEAT_HW_ESP]              = "esp-hw-offload",
-+        [NET_DEV_FEAT_HW_ESP_TX_CSUM]      = "esp-tx-csum-hw-offload",
-+        [NET_DEV_FEAT_RX_UDP_TUNNEL_PORT]  = "rx-udp_tunnel-port-offload",
-+        [NET_DEV_FEAT_HW_TLS_RECORD]       = "tls-hw-record",
-+        [NET_DEV_FEAT_HW_TLS_TX]           = "tls-hw-tx-offload",
-+        [NET_DEV_FEAT_HW_TLS_RX]           = "tls-hw-rx-offload",
-+        [NET_DEV_FEAT_GRO_FRAGLIST]        = "rx-gro-list",
-+        [NET_DEV_FEAT_HW_MACSEC]           = "macsec-hw-offload",
-+        [NET_DEV_FEAT_GRO_UDP_FWD]         = "rx-udp-gro-forwarding",
-+        [NET_DEV_FEAT_HW_HSR_TAG_INS]      = "hsr-tag-ins-offload",
-+        [NET_DEV_FEAT_HW_HSR_TAG_RM]       = "hsr-tag-rm-offload",
-+        [NET_DEV_FEAT_HW_HSR_FWD]          = "hsr-fwd-offload",
-+        [NET_DEV_FEAT_HW_HSR_DUP]          = "hsr-dup-offload",
-+
-+        [NET_DEV_FEAT_TXCSUM]              = "tx-checksum-", /* The suffix "-" means any feature beginning with "tx-checksum-" */
- };
- 
- static const char* const ethtool_link_mode_bit_table[] = {
-diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h
-index 3f2252563304..cc0655893175 100644
---- a/src/shared/ethtool-util.h
-+++ b/src/shared/ethtool-util.h
-@@ -19,16 +19,71 @@ typedef enum Duplex {
- } Duplex;
- 
- typedef enum NetDevFeature {
--        NET_DEV_FEAT_RX,
-+        NET_DEV_FEAT_SG,
-+        NET_DEV_FEAT_IP_CSUM,
-+        NET_DEV_FEAT_HW_CSUM,
-+        NET_DEV_FEAT_IPV6_CSUM,
-+        NET_DEV_FEAT_HIGHDMA,
-+        NET_DEV_FEAT_FRAGLIST,
-+        NET_DEV_FEAT_HW_VLAN_CTAG_TX,
-+        NET_DEV_FEAT_HW_VLAN_CTAG_RX,
-+        NET_DEV_FEAT_HW_VLAN_CTAG_FILTER,
-+        NET_DEV_FEAT_HW_VLAN_STAG_TX,
-+        NET_DEV_FEAT_HW_VLAN_STAG_RX,
-+        NET_DEV_FEAT_HW_VLAN_STAG_FILTER,
-+        NET_DEV_FEAT_VLAN_CHALLENGED,
-         NET_DEV_FEAT_GSO,
-+        NET_DEV_FEAT_LLTX,
-+        NET_DEV_FEAT_NETNS_LOCAL,
-         NET_DEV_FEAT_GRO,
-         NET_DEV_FEAT_GRO_HW,
-         NET_DEV_FEAT_LRO,
-         NET_DEV_FEAT_TSO,
-+        NET_DEV_FEAT_GSO_ROBUST,
-+        NET_DEV_FEAT_TSO_ECN,
-+        NET_DEV_FEAT_TSO_MANGLEID,
-         NET_DEV_FEAT_TSO6,
-+        NET_DEV_FEAT_FSO,
-+        NET_DEV_FEAT_GSO_GRE,
-+        NET_DEV_FEAT_GSO_GRE_CSUM,
-+        NET_DEV_FEAT_GSO_IPXIP4,
-+        NET_DEV_FEAT_GSO_IPXIP6,
-+        NET_DEV_FEAT_GSO_UDP_TUNNEL,
-+        NET_DEV_FEAT_GSO_UDP_TUNNEL_CSUM,
-+        NET_DEV_FEAT_GSO_PARTIAL,
-+        NET_DEV_FEAT_GSO_TUNNEL_REMCSUM,
-+        NET_DEV_FEAT_GSO_SCTP,
-+        NET_DEV_FEAT_GSO_ESP,
-+        NET_DEV_FEAT_GSO_UDP_L4,
-+        NET_DEV_FEAT_GSO_FRAGLIST,
-+        NET_DEV_FEAT_FCOE_CRC,
-+        NET_DEV_FEAT_SCTP_CRC,
-+        NET_DEV_FEAT_FCOE_MTU,
-+        NET_DEV_FEAT_NTUPLE,
-+        NET_DEV_FEAT_RXHASH,
-+        NET_DEV_FEAT_RXCSUM,
-+        NET_DEV_FEAT_NOCACHE_COPY,
-+        NET_DEV_FEAT_LOOPBACK,
-+        NET_DEV_FEAT_RXFCS,
-+        NET_DEV_FEAT_RXALL,
-+        NET_DEV_FEAT_HW_L2FW_DOFFLOAD,
-+        NET_DEV_FEAT_HW_TC,
-+        NET_DEV_FEAT_HW_ESP,
-+        NET_DEV_FEAT_HW_ESP_TX_CSUM,
-+        NET_DEV_FEAT_RX_UDP_TUNNEL_PORT,
-+        NET_DEV_FEAT_HW_TLS_RECORD,
-+        NET_DEV_FEAT_HW_TLS_TX,
-+        NET_DEV_FEAT_HW_TLS_RX,
-+        NET_DEV_FEAT_GRO_FRAGLIST,
-+        NET_DEV_FEAT_HW_MACSEC,
-+        NET_DEV_FEAT_GRO_UDP_FWD,
-+        NET_DEV_FEAT_HW_HSR_TAG_INS,
-+        NET_DEV_FEAT_HW_HSR_TAG_RM,
-+        NET_DEV_FEAT_HW_HSR_FWD,
-+        NET_DEV_FEAT_HW_HSR_DUP,
-         _NET_DEV_FEAT_SIMPLE_MAX,
- 
--        NET_DEV_FEAT_TX = _NET_DEV_FEAT_SIMPLE_MAX,
-+        NET_DEV_FEAT_TXCSUM = _NET_DEV_FEAT_SIMPLE_MAX,
-         _NET_DEV_FEAT_MAX,
-         _NET_DEV_FEAT_INVALID = -EINVAL,
- } NetDevFeature;
-diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
-index 44b46cb17c0b..e3cdaaee0509 100644
---- a/src/udev/net/link-config-gperf.gperf
-+++ b/src/udev/net/link-config-gperf.gperf
-@@ -50,8 +50,8 @@ Link.Duplex,                              config_parse_duplex,
- Link.AutoNegotiation,                     config_parse_tristate,                 0,                             offsetof(LinkConfig, autonegotiation)
- Link.WakeOnLan,                           config_parse_wol,                      0,                             offsetof(LinkConfig, wol)
- Link.Port,                                config_parse_port,                     0,                             offsetof(LinkConfig, port)
--Link.ReceiveChecksumOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
--Link.TransmitChecksumOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
-+Link.ReceiveChecksumOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RXCSUM])
-+Link.TransmitChecksumOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TXCSUM])
- Link.GenericSegmentationOffload,          config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
- Link.TCPSegmentationOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
- Link.TCP6SegmentationOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
diff --git a/20743.patch b/20743.patch
deleted file mode 100644
index 0975ce8..0000000
--- a/20743.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0fc51b569570e8bf5aecd5ee03a88eb668b7b385 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Tue, 14 Sep 2021 16:33:10 -0700
-Subject: [PATCH] fileio: start with 4k buffer for procfs
-
-There's a very gradual increase of anonymous memory in systemd-journald that
-blames to 2ac67221bb6270f0fbe7cbd0076653832cd49de2.
-
-systemd-journald makes many calls to read /proc/PID/cmdline and
-/proc/PID/status, both of which tend to be well under 4K. However the
-combination of allocating 4M read buffers, then using `realloc()` to
-shrink the buffer in `read_virtual_file()` appears to be creating
-fragmentation in the heap (when combined with the other allocations
-systemd-journald is doing).
-
-To help mitigate this, try reading /proc with a 4K buffer as
-`read_virtual_file()` did before 2ac67221bb6270f0fbe7cbd0076653832cd49de2.
-If it isn't big enough then try again with the larger buffers.
----
- src/basic/fileio.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/src/basic/fileio.c b/src/basic/fileio.c
-index 99a44fdea2..466c6321c7 100644
---- a/src/basic/fileio.c
-+++ b/src/basic/fileio.c
-@@ -431,6 +431,11 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
-                         }
- 
-                         n_retries--;
-+                } else if (n_retries > 1) {
-+                        /* Files in /proc are generally smaller than the page size so let's start with a page size
-+                         * buffer from malloc and only use the max buffer on the final try. */
-+                        size = MIN3(page_size() - 1, READ_VIRTUAL_BYTES_MAX, max_size);
-+                        n_retries = 1;
-                 } else {
-                         size = MIN(READ_VIRTUAL_BYTES_MAX, max_size);
-                         n_retries = 0;
--- 
-2.31.1
-
diff --git a/20828.patch b/20828.patch
deleted file mode 100644
index 2b55bd4..0000000
--- a/20828.patch
+++ /dev/null
@@ -1,240 +0,0 @@
-From 88eca13f57194765d184ca227320df83f48020e2 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Fri, 24 Sep 2021 01:19:00 -0700
-Subject: [PATCH] link: connect 5 more properties to ethtool features
-
-Sets up the follow properties and their corresponding ethtool feature:
-- ReceiveVLANCTAGHardwareAcceleration == rx-vlan-hw-parse (or rxvlan)
-- TransmitVLANCTAGHardwareAcceleration == tx-vlan-hw-insert (or txvlan)
-- ReceiveVLANCTAGFilter == rx-vlan-filter
-- TransmitVLANSTAGHardwareAcceleration == tx-vlan-stag-hw-insert
-- NTupleFilter == rx-ntuple-filter (or ntuple)
----
- man/systemd.link.xml                       |  35 +++++
- src/udev/net/link-config-gperf.gperf       | 153 +++++++++++----------
- test/fuzz/fuzz-link-parser/directives.link |   5 +
- 3 files changed, 119 insertions(+), 74 deletions(-)
-
-diff --git a/man/systemd.link.xml b/man/systemd.link.xml
-index 638a1522cd38..c8d3c5137459 100644
---- a/man/systemd.link.xml
-+++ b/man/systemd.link.xml
-@@ -715,6 +715,41 @@
-           When unset, the kernel's default will be used.</para>
-         </listitem>
-       </varlistentry>
-+      <varlistentry>
-+        <term><varname>ReceiveVLANCTAGHardwareAcceleration=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, receive VLAN CTAG hardware acceleration is enabled.
-+          When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>TransmitVLANCTAGHardwareAcceleration=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, transmit VLAN CTAG hardware acceleration is enabled.
-+          When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>ReceiveVLANCTAGFilter=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, receive filtering on VLAN CTAGs is enabled.
-+          When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>TransmitVLANSTAGHardwareAcceleration=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, transmit VLAN STAG HW acceleration is enabled.
-+          When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-+      <varlistentry>
-+        <term><varname>NTupleFilter=</varname></term>
-+        <listitem>
-+          <para>Takes a boolean. If set to true, receive N-tuple filters and actions are enabled.
-+          When unset, the kernel's default will be used.</para>
-+        </listitem>
-+      </varlistentry>
-       <varlistentry>
-         <term><varname>RxChannels=</varname></term>
-         <term><varname>TxChannels=</varname></term>
-diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
-index e3cdaaee0509..04c255ce514c 100644
---- a/src/udev/net/link-config-gperf.gperf
-+++ b/src/udev/net/link-config-gperf.gperf
-@@ -21,77 +21,82 @@ struct ConfigPerfItem;
- %struct-type
- %includes
- %%
--Match.MACAddress,                         config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.mac)
--Match.PermanentMACAddress,                config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.permanent_mac)
--Match.OriginalName,                       config_parse_match_ifnames,            0,                             offsetof(LinkConfig, match.ifname)
--Match.Path,                               config_parse_match_strv,               0,                             offsetof(LinkConfig, match.path)
--Match.Driver,                             config_parse_match_strv,               0,                             offsetof(LinkConfig, match.driver)
--Match.Type,                               config_parse_match_strv,               0,                             offsetof(LinkConfig, match.iftype)
--Match.Property,                           config_parse_match_property,           0,                             offsetof(LinkConfig, match.property)
--Match.Host,                               config_parse_net_condition,            CONDITION_HOST,                offsetof(LinkConfig, conditions)
--Match.Virtualization,                     config_parse_net_condition,            CONDITION_VIRTUALIZATION,      offsetof(LinkConfig, conditions)
--Match.KernelCommandLine,                  config_parse_net_condition,            CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
--Match.KernelVersion,                      config_parse_net_condition,            CONDITION_KERNEL_VERSION,      offsetof(LinkConfig, conditions)
--Match.Architecture,                       config_parse_net_condition,            CONDITION_ARCHITECTURE,        offsetof(LinkConfig, conditions)
--Link.Description,                         config_parse_string,                   0,                             offsetof(LinkConfig, description)
--Link.MACAddressPolicy,                    config_parse_mac_address_policy,       0,                             offsetof(LinkConfig, mac_address_policy)
--Link.MACAddress,                          config_parse_hwaddr,                   0,                             offsetof(LinkConfig, mac)
--Link.NamePolicy,                          config_parse_name_policy,              0,                             offsetof(LinkConfig, name_policy)
--Link.Name,                                config_parse_ifname,                   0,                             offsetof(LinkConfig, name)
--Link.AlternativeName,                     config_parse_ifnames,                  IFNAME_VALID_ALTERNATIVE,      offsetof(LinkConfig, alternative_names)
--Link.AlternativeNamesPolicy,              config_parse_alternative_names_policy, 0,                             offsetof(LinkConfig, alternative_names_policy)
--Link.Alias,                               config_parse_ifalias,                  0,                             offsetof(LinkConfig, alias)
--Link.TransmitQueues,                      config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, txqueues)
--Link.ReceiveQueues,                       config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, rxqueues)
--Link.TransmitQueueLength,                 config_parse_txqueuelen,               0,                             offsetof(LinkConfig, txqueuelen)
--Link.MTUBytes,                            config_parse_mtu,                      AF_UNSPEC,                     offsetof(LinkConfig, mtu)
--Link.BitsPerSecond,                       config_parse_si_uint64,                0,                             offsetof(LinkConfig, speed)
--Link.Duplex,                              config_parse_duplex,                   0,                             offsetof(LinkConfig, duplex)
--Link.AutoNegotiation,                     config_parse_tristate,                 0,                             offsetof(LinkConfig, autonegotiation)
--Link.WakeOnLan,                           config_parse_wol,                      0,                             offsetof(LinkConfig, wol)
--Link.Port,                                config_parse_port,                     0,                             offsetof(LinkConfig, port)
--Link.ReceiveChecksumOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RXCSUM])
--Link.TransmitChecksumOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TXCSUM])
--Link.GenericSegmentationOffload,          config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
--Link.TCPSegmentationOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
--Link.TCP6SegmentationOffload,             config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
--Link.UDPSegmentationOffload,              config_parse_warn_compat,              DISABLED_LEGACY,               0
--Link.GenericReceiveOffload,               config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
--Link.GenericReceiveOffloadHardware,       config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_HW])
--Link.LargeReceiveOffload,                 config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
--Link.RxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
--Link.TxChannels,                          config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
--Link.OtherChannels,                       config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.other)
--Link.CombinedChannels,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.combined)
--Link.Advertise,                           config_parse_advertise,                0,                             offsetof(LinkConfig, advertise)
--Link.RxBufferSize,                        config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx)
--Link.RxMiniBufferSize,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_mini)
--Link.RxJumboBufferSize,                   config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_jumbo)
--Link.TxBufferSize,                        config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.tx)
--Link.RxFlowControl,                       config_parse_tristate,                 0,                             offsetof(LinkConfig, rx_flow_control)
--Link.TxFlowControl,                       config_parse_tristate,                 0,                             offsetof(LinkConfig, tx_flow_control)
--Link.AutoNegotiationFlowControl,          config_parse_tristate,                 0,                             offsetof(LinkConfig, autoneg_flow_control)
--Link.GenericSegmentOffloadMaxBytes,       config_parse_iec_size,                 0,                             offsetof(LinkConfig, gso_max_size)
--Link.GenericSegmentOffloadMaxSegments,    config_parse_uint32,                   0,                             offsetof(LinkConfig, gso_max_segments)
--Link.RxCoalesceSec,                       config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
--Link.RxMaxCoalescedFrames,                config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
--Link.RxCoalesceIrqSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
--Link.RxMaxCoalescedIrqFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_irq)
--Link.TxCoalesceSec,                       config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs)
--Link.TxMaxCoalescedFrames,                config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames)
--Link.TxCoalesceIrqSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_irq)
--Link.TxMaxCoalescedIrqFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_irq)
--Link.StatisticsBlockCoalesceSec,          config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.stats_block_coalesce_usecs)
--Link.UseAdaptiveRxCoalesce,               config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_rx_coalesce)
--Link.UseAdaptiveTxCoalesce,               config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_tx_coalesce)
--Link.CoalescePacketRateLow,               config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_low)
--Link.RxCoalesceLowSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_low)
--Link.RxMaxCoalescedLowFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_low)
--Link.TxCoalesceLowSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_low)
--Link.TxMaxCoalescedLowFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_low)
--Link.CoalescePacketRateHigh,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_high)
--Link.RxCoalesceHighSec,                   config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_high)
--Link.RxMaxCoalescedHighFrames,            config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_high)
--Link.TxCoalesceHighSec,                   config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
--Link.TxMaxCoalescedHighFrames,            config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
--Link.CoalescePacketRateSampleIntervalSec, config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rate_sample_interval)
-+Match.MACAddress,                          config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.mac)
-+Match.PermanentMACAddress,                 config_parse_hwaddrs,                  0,                             offsetof(LinkConfig, match.permanent_mac)
-+Match.OriginalName,                        config_parse_match_ifnames,            0,                             offsetof(LinkConfig, match.ifname)
-+Match.Path,                                config_parse_match_strv,               0,                             offsetof(LinkConfig, match.path)
-+Match.Driver,                              config_parse_match_strv,               0,                             offsetof(LinkConfig, match.driver)
-+Match.Type,                                config_parse_match_strv,               0,                             offsetof(LinkConfig, match.iftype)
-+Match.Property,                            config_parse_match_property,           0,                             offsetof(LinkConfig, match.property)
-+Match.Host,                                config_parse_net_condition,            CONDITION_HOST,                offsetof(LinkConfig, conditions)
-+Match.Virtualization,                      config_parse_net_condition,            CONDITION_VIRTUALIZATION,      offsetof(LinkConfig, conditions)
-+Match.KernelCommandLine,                   config_parse_net_condition,            CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
-+Match.KernelVersion,                       config_parse_net_condition,            CONDITION_KERNEL_VERSION,      offsetof(LinkConfig, conditions)
-+Match.Architecture,                        config_parse_net_condition,            CONDITION_ARCHITECTURE,        offsetof(LinkConfig, conditions)
-+Link.Description,                          config_parse_string,                   0,                             offsetof(LinkConfig, description)
-+Link.MACAddressPolicy,                     config_parse_mac_address_policy,       0,                             offsetof(LinkConfig, mac_address_policy)
-+Link.MACAddress,                           config_parse_hwaddr,                   0,                             offsetof(LinkConfig, mac)
-+Link.NamePolicy,                           config_parse_name_policy,              0,                             offsetof(LinkConfig, name_policy)
-+Link.Name,                                 config_parse_ifname,                   0,                             offsetof(LinkConfig, name)
-+Link.AlternativeName,                      config_parse_ifnames,                  IFNAME_VALID_ALTERNATIVE,      offsetof(LinkConfig, alternative_names)
-+Link.AlternativeNamesPolicy,               config_parse_alternative_names_policy, 0,                             offsetof(LinkConfig, alternative_names_policy)
-+Link.Alias,                                config_parse_ifalias,                  0,                             offsetof(LinkConfig, alias)
-+Link.TransmitQueues,                       config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, txqueues)
-+Link.ReceiveQueues,                        config_parse_rx_tx_queues,             0,                             offsetof(LinkConfig, rxqueues)
-+Link.TransmitQueueLength,                  config_parse_txqueuelen,               0,                             offsetof(LinkConfig, txqueuelen)
-+Link.MTUBytes,                             config_parse_mtu,                      AF_UNSPEC,                     offsetof(LinkConfig, mtu)
-+Link.BitsPerSecond,                        config_parse_si_uint64,                0,                             offsetof(LinkConfig, speed)
-+Link.Duplex,                               config_parse_duplex,                   0,                             offsetof(LinkConfig, duplex)
-+Link.AutoNegotiation,                      config_parse_tristate,                 0,                             offsetof(LinkConfig, autonegotiation)
-+Link.WakeOnLan,                            config_parse_wol,                      0,                             offsetof(LinkConfig, wol)
-+Link.Port,                                 config_parse_port,                     0,                             offsetof(LinkConfig, port)
-+Link.ReceiveChecksumOffload,               config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_RXCSUM])
-+Link.TransmitChecksumOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TXCSUM])
-+Link.GenericSegmentationOffload,           config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
-+Link.TCPSegmentationOffload,               config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
-+Link.TCP6SegmentationOffload,              config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
-+Link.UDPSegmentationOffload,               config_parse_warn_compat,              DISABLED_LEGACY,               0
-+Link.GenericReceiveOffload,                config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
-+Link.GenericReceiveOffloadHardware,        config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_HW])
-+Link.LargeReceiveOffload,                  config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
-+Link.ReceiveVLANCTAGHardwareAcceleration,  config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_CTAG_RX])
-+Link.TransmitVLANCTAGHardwareAcceleration, config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_CTAG_TX])
-+Link.ReceiveVLANCTAGFilter,                config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_CTAG_FILTER])
-+Link.TransmitVLANSTAGHardwareAcceleration, config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_STAG_TX])
-+Link.NTupleFilter,                         config_parse_tristate,                 0,                             offsetof(LinkConfig, features[NET_DEV_FEAT_NTUPLE])
-+Link.RxChannels,                           config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.rx)
-+Link.TxChannels,                           config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.tx)
-+Link.OtherChannels,                        config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.other)
-+Link.CombinedChannels,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, channels.combined)
-+Link.Advertise,                            config_parse_advertise,                0,                             offsetof(LinkConfig, advertise)
-+Link.RxBufferSize,                         config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx)
-+Link.RxMiniBufferSize,                     config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_mini)
-+Link.RxJumboBufferSize,                    config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.rx_jumbo)
-+Link.TxBufferSize,                         config_parse_ring_buffer_or_channel,   0,                             offsetof(LinkConfig, ring.tx)
-+Link.RxFlowControl,                        config_parse_tristate,                 0,                             offsetof(LinkConfig, rx_flow_control)
-+Link.TxFlowControl,                        config_parse_tristate,                 0,                             offsetof(LinkConfig, tx_flow_control)
-+Link.AutoNegotiationFlowControl,           config_parse_tristate,                 0,                             offsetof(LinkConfig, autoneg_flow_control)
-+Link.GenericSegmentOffloadMaxBytes,        config_parse_iec_size,                 0,                             offsetof(LinkConfig, gso_max_size)
-+Link.GenericSegmentOffloadMaxSegments,     config_parse_uint32,                   0,                             offsetof(LinkConfig, gso_max_segments)
-+Link.RxCoalesceSec,                        config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
-+Link.RxMaxCoalescedFrames,                 config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
-+Link.RxCoalesceIrqSec,                     config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
-+Link.RxMaxCoalescedIrqFrames,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_irq)
-+Link.TxCoalesceSec,                        config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs)
-+Link.TxMaxCoalescedFrames,                 config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames)
-+Link.TxCoalesceIrqSec,                     config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_irq)
-+Link.TxMaxCoalescedIrqFrames,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_irq)
-+Link.StatisticsBlockCoalesceSec,           config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.stats_block_coalesce_usecs)
-+Link.UseAdaptiveRxCoalesce,                config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_rx_coalesce)
-+Link.UseAdaptiveTxCoalesce,                config_parse_tristate,                 0,                             offsetof(LinkConfig, coalesce.use_adaptive_tx_coalesce)
-+Link.CoalescePacketRateLow,                config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_low)
-+Link.RxCoalesceLowSec,                     config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_low)
-+Link.RxMaxCoalescedLowFrames,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_low)
-+Link.TxCoalesceLowSec,                     config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_low)
-+Link.TxMaxCoalescedLowFrames,              config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_low)
-+Link.CoalescePacketRateHigh,               config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.pkt_rate_high)
-+Link.RxCoalesceHighSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rx_coalesce_usecs_high)
-+Link.RxMaxCoalescedHighFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_high)
-+Link.TxCoalesceHighSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
-+Link.TxMaxCoalescedHighFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
-+Link.CoalescePacketRateSampleIntervalSec,  config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rate_sample_interval)
-diff --git a/test/fuzz/fuzz-link-parser/directives.link b/test/fuzz/fuzz-link-parser/directives.link
-index b5cffb1a271f..8be2434665a7 100644
---- a/test/fuzz/fuzz-link-parser/directives.link
-+++ b/test/fuzz/fuzz-link-parser/directives.link
-@@ -38,6 +38,11 @@ UDPSegmentationOffload=
- GenericReceiveOffload=
- GenericReceiveOffloadHardware=
- LargeReceiveOffload=
-+ReceiveVLANCTAGHardwareAcceleration=
-+TransmitVLANCTAGHardwareAcceleration=
-+ReceiveVLANCTAGFilter=
-+TransmitVLANSTAGHardwareAcceleration=
-+NTupleFilter=
- RxChannels=
- TxChannels=
- OtherChannels=
diff --git a/20875.patch b/20875.patch
deleted file mode 100644
index 610ee4c..0000000
--- a/20875.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 84e1818ce1dc9f5f7eb7b4d4bc87124d82c5080f Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Tue, 28 Sep 2021 23:52:39 -0700
-Subject: [PATCH] basic/unit-file: don't filter out names starting with dot
-
-Fixes #20859
----
- src/basic/unit-file.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c
-index 884a0674a9..0d58b1c4fe 100644
---- a/src/basic/unit-file.c
-+++ b/src/basic/unit-file.c
-@@ -284,7 +284,7 @@ int unit_file_build_name_map(
-                         continue;
-                 }
- 
--                FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
-+                FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
-                         char *filename;
-                         _cleanup_free_ char *_filename_free = NULL, *simplified = NULL;
-                         const char *suffix, *dst = NULL;
--- 
-2.31.1
-
diff --git a/20978.patch b/20978.patch
deleted file mode 100644
index 8330e00..0000000
--- a/20978.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From a58dea6130fdcccd8cdf50633c939b45e2b32189 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Mon, 11 Oct 2021 00:25:20 -0700
-Subject: [PATCH] core: serialize device cgroup bpf progs across
- daemon-reload/reexec
-
-Follows what was done in b57d75232615f98aefcf41cb145ec2ea3262857d and
-adds a test that verifies the device BPF program is not detached during
-reload/reexec.
----
- src/core/unit-serialize.c                     |  4 ++++
- test/TEST-66-DEVICE-ISOLATION/Makefile        |  1 +
- test/TEST-66-DEVICE-ISOLATION/test.sh         | 10 ++++++++
- .../testsuite-66-deviceisolation.service      |  9 ++++++++
- test/units/testsuite-66.service               |  7 ++++++
- test/units/testsuite-66.sh                    | 23 +++++++++++++++++++
- 6 files changed, 54 insertions(+)
- create mode 120000 test/TEST-66-DEVICE-ISOLATION/Makefile
- create mode 100755 test/TEST-66-DEVICE-ISOLATION/test.sh
- create mode 100644 test/units/testsuite-66-deviceisolation.service
- create mode 100644 test/units/testsuite-66.service
- create mode 100755 test/units/testsuite-66.sh
-
-diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c
-index 9e1664ff53af..3458d7017bd5 100644
---- a/src/core/unit-serialize.c
-+++ b/src/core/unit-serialize.c
-@@ -171,6 +171,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
- 
-         (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", u->ip_bpf_ingress_installed);
-         (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-egress-installed", u->ip_bpf_egress_installed);
-+        (void) bpf_program_serialize_attachment(f, fds, "bpf-device-control-installed", u->bpf_device_control_installed);
-         (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-ingress-installed", u->ip_bpf_custom_ingress_installed);
-         (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-egress-installed", u->ip_bpf_custom_egress_installed);
- 
-@@ -408,6 +409,9 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
-                 } else if (streq(l, "ip-bpf-egress-installed")) {
-                          (void) bpf_program_deserialize_attachment(v, fds, &u->ip_bpf_egress_installed);
-                          continue;
-+                } else if (streq(l, "bpf-device-control-installed")) {
-+                         (void) bpf_program_deserialize_attachment(v, fds, &u->bpf_device_control_installed);
-+                         continue;
- 
-                 } else if (streq(l, "ip-bpf-custom-ingress-installed")) {
-                          (void) bpf_program_deserialize_attachment_set(v, fds, &u->ip_bpf_custom_ingress_installed);
-diff --git a/test/TEST-66-DEVICE-ISOLATION/Makefile b/test/TEST-66-DEVICE-ISOLATION/Makefile
-new file mode 120000
-index 000000000000..e9f93b1104cd
---- /dev/null
-+++ b/test/TEST-66-DEVICE-ISOLATION/Makefile
-@@ -0,0 +1 @@
-+../TEST-01-BASIC/Makefile
-\ No newline at end of file
-diff --git a/test/TEST-66-DEVICE-ISOLATION/test.sh b/test/TEST-66-DEVICE-ISOLATION/test.sh
-new file mode 100755
-index 000000000000..534e43e493e6
---- /dev/null
-+++ b/test/TEST-66-DEVICE-ISOLATION/test.sh
-@@ -0,0 +1,10 @@
-+#!/usr/bin/env bash
-+set -e
-+
-+TEST_DESCRIPTION="test device isolation"
-+TEST_NO_NSPAWN=1
-+
-+# shellcheck source=test/test-functions
-+. "${TEST_BASE_DIR:?}/test-functions"
-+
-+do_test "$@"
-diff --git a/test/units/testsuite-66-deviceisolation.service b/test/units/testsuite-66-deviceisolation.service
-new file mode 100644
-index 000000000000..0022a9a45724
---- /dev/null
-+++ b/test/units/testsuite-66-deviceisolation.service
-@@ -0,0 +1,9 @@
-+[Unit]
-+Description=Service that uses device isolation
-+
-+[Service]
-+DevicePolicy=strict
-+DeviceAllow=/dev/null r
-+StandardOutput=file:/testsuite66serviceresults
-+ExecStartPre=rm -f /testsuite66serviceresults
-+ExecStart=/bin/bash -c "while true; do sleep 0.01 && echo meow > /dev/null && echo thisshouldnotbehere; done"
-diff --git a/test/units/testsuite-66.service b/test/units/testsuite-66.service
-new file mode 100644
-index 000000000000..a97974a4262d
---- /dev/null
-+++ b/test/units/testsuite-66.service
-@@ -0,0 +1,7 @@
-+[Unit]
-+Description=TESTSUITE-66-DEVICEISOLATION
-+
-+[Service]
-+ExecStartPre=rm -f /failed /testok
-+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-+Type=oneshot
-diff --git a/test/units/testsuite-66.sh b/test/units/testsuite-66.sh
-new file mode 100755
-index 000000000000..870dca42e169
---- /dev/null
-+++ b/test/units/testsuite-66.sh
-@@ -0,0 +1,23 @@
-+#!/usr/bin/env bash
-+set -eux
-+set -o pipefail
-+
-+systemd-analyze log-level debug
-+systemd-analyze log-target console
-+
-+systemctl start testsuite-66-deviceisolation.service
-+
-+grep -q "Operation not permitted" /testsuite66serviceresults
-+
-+systemctl daemon-reload
-+systemctl daemon-reexec
-+
-+systemctl stop testsuite-66-deviceisolation.service
-+
-+grep -q "thisshouldnotbehere" /testsuite66serviceresults && exit 42
-+
-+systemd-analyze log-level info
-+
-+echo OK >/testok
-+
-+exit 0
diff --git a/21221.patch b/21221.patch
deleted file mode 100644
index cfe113e..0000000
--- a/21221.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From fbdc87679cc4f3c9fc3653636e94be20f06d18e4 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Tue, 9 Nov 2021 15:26:28 -0800
-Subject: [PATCH] core: replace slice dependencies as they get added
-
-Defines a "UNIT_DEPENDENCY_SLICE_PROPERTY" UnitDependencyMask type that
-is used when adding slices to the dependencies hashmap. This type is
-used to remove slice dependencies when they get overridden by new ones.
-
-Fixes #20182
----
- src/core/dbus-unit.c      |  2 +-
- src/core/load-fragment.c  |  2 +-
- src/core/unit-serialize.c |  1 +
- src/core/unit.c           | 10 +++++++---
- src/core/unit.h           |  7 +++++--
- src/test/test-engine.c    | 31 ++++++++++++++++++++++++++++++-
- 6 files changed, 45 insertions(+), 8 deletions(-)
-
-diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
-index fe320f1b05a8..d4ec789a7c11 100644
---- a/src/core/dbus-unit.c
-+++ b/src/core/dbus-unit.c
-@@ -2273,7 +2273,7 @@ static int bus_unit_set_transient_property(
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s);
- 
-                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
--                        r = unit_set_slice(u, slice, UNIT_DEPENDENCY_FILE);
-+                        r = unit_set_slice(u, slice);
-                         if (r < 0)
-                                 return r;
- 
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
-index 62cadaf2286f..830048ae1915 100644
---- a/src/core/load-fragment.c
-+++ b/src/core/load-fragment.c
-@@ -3792,7 +3792,7 @@ int config_parse_unit_slice(
-                 return 0;
-         }
- 
--        r = unit_set_slice(u, slice, UNIT_DEPENDENCY_FILE);
-+        r = unit_set_slice(u, slice);
-         if (r < 0) {
-                 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to assign slice %s to unit %s, ignoring: %m", slice->id, u->id);
-                 return 0;
-diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c
-index 3458d7017bd5..7d2e6bc130de 100644
---- a/src/core/unit-serialize.c
-+++ b/src/core/unit-serialize.c
-@@ -593,6 +593,7 @@ static void print_unit_dependency_mask(FILE *f, const char *kind, UnitDependency
-                 { UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT, "mountinfo-implicit" },
-                 { UNIT_DEPENDENCY_MOUNTINFO_DEFAULT,  "mountinfo-default"  },
-                 { UNIT_DEPENDENCY_PROC_SWAP,          "proc-swap"          },
-+                { UNIT_DEPENDENCY_SLICE_PROPERTY,     "slice-property"     },
-         };
- 
-         assert(f);
-diff --git a/src/core/unit.c b/src/core/unit.c
-index 4c55827a6511..a3bca43566e0 100644
---- a/src/core/unit.c
-+++ b/src/core/unit.c
-@@ -3284,7 +3284,7 @@ int unit_set_invocation_id(Unit *u, sd_id128_t id) {
-         return r;
- }
- 
--int unit_set_slice(Unit *u, Unit *slice, UnitDependencyMask mask) {
-+int unit_set_slice(Unit *u, Unit *slice) {
-         int r;
- 
-         assert(u);
-@@ -3317,7 +3317,11 @@ int unit_set_slice(Unit *u, Unit *slice, UnitDependencyMask mask) {
-         if (UNIT_GET_SLICE(u) && u->cgroup_realized)
-                 return -EBUSY;
- 
--        r = unit_add_dependency(u, UNIT_IN_SLICE, slice, true, mask);
-+        /* Remove any slices assigned prior; we should only have one UNIT_IN_SLICE dependency */
-+        if (UNIT_GET_SLICE(u))
-+                unit_remove_dependencies(u, UNIT_DEPENDENCY_SLICE_PROPERTY);
-+
-+        r = unit_add_dependency(u, UNIT_IN_SLICE, slice, true, UNIT_DEPENDENCY_SLICE_PROPERTY);
-         if (r < 0)
-                 return r;
- 
-@@ -3373,7 +3377,7 @@ int unit_set_default_slice(Unit *u) {
-         if (r < 0)
-                 return r;
- 
--        return unit_set_slice(u, slice, UNIT_DEPENDENCY_FILE);
-+        return unit_set_slice(u, slice);
- }
- 
- const char *unit_slice_name(Unit *u) {
-diff --git a/src/core/unit.h b/src/core/unit.h
-index 0dd6a9591d96..ba12fe4ac1ef 100644
---- a/src/core/unit.h
-+++ b/src/core/unit.h
-@@ -89,7 +89,10 @@ typedef enum UnitDependencyMask {
-         /* A dependency created because of data read from /proc/swaps and no other configuration source */
-         UNIT_DEPENDENCY_PROC_SWAP          = 1 << 7,
- 
--        _UNIT_DEPENDENCY_MASK_FULL         = (1 << 8) - 1,
-+        /* A dependency for units in slices assigned by directly setting Slice= */
-+        UNIT_DEPENDENCY_SLICE_PROPERTY     = 1 << 8,
-+
-+        _UNIT_DEPENDENCY_MASK_FULL         = (1 << 9) - 1,
- } UnitDependencyMask;
- 
- /* The Unit's dependencies[] hashmaps use this structure as value. It has the same size as a void pointer, and thus can
-@@ -782,7 +785,7 @@ Unit *unit_follow_merge(Unit *u) _pure_;
- int unit_load_fragment_and_dropin(Unit *u, bool fragment_required);
- int unit_load(Unit *unit);
- 
--int unit_set_slice(Unit *u, Unit *slice, UnitDependencyMask mask);
-+int unit_set_slice(Unit *u, Unit *slice);
- int unit_set_default_slice(Unit *u);
- 
- const char *unit_description(Unit *u) _pure_;
-diff --git a/src/test/test-engine.c b/src/test/test-engine.c
-index 880af36fb523..673c66561240 100644
---- a/src/test/test-engine.c
-+++ b/src/test/test-engine.c
-@@ -8,6 +8,7 @@
- #include "manager-dump.h"
- #include "rm-rf.h"
- #include "service.h"
-+#include "slice.h"
- #include "special.h"
- #include "strv.h"
- #include "tests.h"
-@@ -75,7 +76,8 @@ int main(int argc, char *argv[]) {
-         _cleanup_(sd_bus_error_free) sd_bus_error err = SD_BUS_ERROR_NULL;
-         _cleanup_(manager_freep) Manager *m = NULL;
-         Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL,
--                *h = NULL, *i = NULL, *a_conj = NULL, *unit_with_multiple_dashes = NULL, *stub = NULL;
-+                *h = NULL, *i = NULL, *a_conj = NULL, *unit_with_multiple_dashes = NULL, *stub = NULL,
-+                *tomato = NULL, *sauce = NULL, *fruit = NULL, *zupa = NULL;
-         Job *j;
-         int r;
- 
-@@ -260,5 +262,32 @@ int main(int argc, char *argv[]) {
- 
-         verify_dependency_atoms();
- 
-+        /* Test adding multiple Slice= dependencies; only the last should remain */
-+        assert_se(unit_new_for_name(m, sizeof(Service), "tomato.service", &tomato) >= 0);
-+        assert_se(unit_new_for_name(m, sizeof(Slice), "sauce.slice", &sauce) >= 0);
-+        assert_se(unit_new_for_name(m, sizeof(Slice), "fruit.slice", &fruit) >= 0);
-+        assert_se(unit_new_for_name(m, sizeof(Slice), "zupa.slice", &zupa) >= 0);
-+
-+        unit_set_slice(tomato, sauce);
-+        unit_set_slice(tomato, fruit);
-+        unit_set_slice(tomato, zupa);
-+
-+        assert_se(UNIT_GET_SLICE(tomato) == zupa);
-+        assert_se(!unit_has_dependency(tomato, UNIT_ATOM_IN_SLICE, sauce));
-+        assert_se(!unit_has_dependency(tomato, UNIT_ATOM_IN_SLICE, fruit));
-+        assert_se(unit_has_dependency(tomato, UNIT_ATOM_IN_SLICE, zupa));
-+
-+        assert_se(!unit_has_dependency(tomato, UNIT_ATOM_REFERENCES, sauce));
-+        assert_se(!unit_has_dependency(tomato, UNIT_ATOM_REFERENCES, fruit));
-+        assert_se(unit_has_dependency(tomato, UNIT_ATOM_REFERENCES, zupa));
-+
-+        assert_se(!unit_has_dependency(sauce, UNIT_ATOM_SLICE_OF, tomato));
-+        assert_se(!unit_has_dependency(fruit, UNIT_ATOM_SLICE_OF, tomato));
-+        assert_se(unit_has_dependency(zupa, UNIT_ATOM_SLICE_OF, tomato));
-+
-+        assert_se(!unit_has_dependency(sauce, UNIT_ATOM_REFERENCED_BY, tomato));
-+        assert_se(!unit_has_dependency(fruit, UNIT_ATOM_REFERENCED_BY, tomato));
-+        assert_se(unit_has_dependency(zupa, UNIT_ATOM_REFERENCED_BY, tomato));
-+
-         return 0;
- }
diff --git a/21241.patch b/21241.patch
deleted file mode 100644
index 5889a9c..0000000
--- a/21241.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 084d0849fc864b0377551b211def7a89b642c5e9 Mon Sep 17 00:00:00 2001
-From: Julia Kartseva <hex@fb.com>
-Date: Thu, 4 Nov 2021 18:52:02 -0700
-Subject: [PATCH 1/2] core: fix bpf-foreign cg controller realization
-
-Requiring /sys/fs/bpf path to be a mount point at the moment of cgroup
-controllers realization does more harm than good, because:
-* Realization happens early on boot, the mount point may not be ready at
-the time. That happens if mounts are made by a .mount unit (the issue we
-encountered).
-* BPF filesystem may be mounted on another point.
-
-Remove the check. Instead verify that path provided by BPFProgram= is
-within BPF fs when unit properties are parsed.
-
-Split in two commits for simple backport.
----
- src/core/bpf-foreign.c | 10 ----------
- src/core/bpf-foreign.h |  5 ++++-
- 2 files changed, 4 insertions(+), 11 deletions(-)
-
-diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c
-index 6b93b9785fb5..686c14ce1f18 100644
---- a/src/core/bpf-foreign.c
-+++ b/src/core/bpf-foreign.c
-@@ -111,16 +111,6 @@ static int bpf_foreign_prepare(
-         return 0;
- }
- 
--int bpf_foreign_supported(void) {
--        int r;
--
--        r = cg_all_unified();
--        if (r <= 0)
--                return r;
--
--        return path_is_mount_point("/sys/fs/bpf", NULL, 0);
--}
--
- int bpf_foreign_install(Unit *u) {
-         _cleanup_free_ char *cgroup_path = NULL;
-         CGroupBPFForeignProgram *p;
-diff --git a/src/core/bpf-foreign.h b/src/core/bpf-foreign.h
-index 9559cd79812b..e387b1b1d389 100644
---- a/src/core/bpf-foreign.h
-+++ b/src/core/bpf-foreign.h
-@@ -4,7 +4,10 @@
- 
- #include "unit.h"
- 
--int bpf_foreign_supported(void);
-+static inline int bpf_foreign_supported(void) {
-+        return cg_all_unified();
-+}
-+
- /*
-  * Attach cgroup-bpf programs foreign to systemd, i.e. loaded to the kernel by an entity
-  * external to systemd.
-
-From dedca960afdee5797d19929c43853513711e3e3d Mon Sep 17 00:00:00 2001
-From: Julia Kartseva <hex@fb.com>
-Date: Thu, 4 Nov 2021 18:55:55 -0700
-Subject: [PATCH 2/2] core: check fs type of BPFProgram= property path
-
-Tests:
-
-```
-% stat --file-system --format="%T" /root/bpf/trivial/
-bpf_fs
-
-% systemd-nspawn -D/ --volatile=yes \
---property=BPFProgram=egress:/root/bpf/trivial/cgroup_skb_egress \
---quiet -- ping -c 5 -W 1 ::1
-PING ::1(::1) 56 data bytes
-
---- ::1 ping statistics ---
-5 packets transmitted, 0 received, 100% packet loss, time 4110ms
-```
-
-```
-% stat --file-system --format='%T' /root/meh
-btrfs
-
-% systemd-nspawn -D/ --volatile=yes --property=BPFProgram=egress:/root/meh
---quiet -- ping -c 5 -W 1 ::1
-```
-sudo ./build/systemd-nspawn \
--D/ --volatile=yes --property=BPFProgram=egress:/home/hex --quiet -- \
-ping -c 1 -W 1 ::1
-PING ::1(::1) 56 data bytes
-64 bytes from ::1: icmp_seq=1 ttl=64 time=0.017 ms
-
---- ::1 ping statistics ---
-1 packets transmitted, 1 received, 0% packet loss, time 0ms
----
- src/core/bpf-foreign.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c
-index 686c14ce1f18..8538792b60db 100644
---- a/src/core/bpf-foreign.c
-+++ b/src/core/bpf-foreign.c
-@@ -4,8 +4,10 @@
- #include "bpf-program.h"
- #include "cgroup.h"
- #include "memory-util.h"
-+#include "missing_magic.h"
- #include "mountpoint-util.h"
- #include "set.h"
-+#include "stat-util.h"
- 
- typedef struct BPFForeignKey BPFForeignKey;
- struct BPFForeignKey {
-@@ -84,6 +86,14 @@ static int bpf_foreign_prepare(
-         assert(u);
-         assert(bpffs_path);
- 
-+        r = path_is_fs_type(bpffs_path, BPF_FS_MAGIC);
-+        if (r < 0)
-+                return log_unit_error_errno(u, r,
-+                                "Failed to determine filesystem type of %s: %m", bpffs_path);
-+        if (r == 0)
-+                return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
-+                                "Path in BPF filesystem is expected.");
-+
-         r = bpf_program_new_from_bpffs_path(bpffs_path, &prog);
-         if (r < 0)
-                 return log_unit_error_errno(u, r, "Failed to create foreign BPFProgram: %m");
diff --git a/21705.patch b/21705.patch
new file mode 100644
index 0000000..51d5714
--- /dev/null
+++ b/21705.patch
@@ -0,0 +1,29 @@
+From ca52de3b56d5e70232bee29314cd84f5596c1e7f Mon Sep 17 00:00:00 2001
+From: Daan De Meyer <daan.j.demeyer@gmail.com>
+Date: Thu, 9 Dec 2021 15:46:13 +0100
+Subject: [PATCH] process-util: Fix memory leak
+
+---
+ src/basic/process-util.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/basic/process-util.c b/src/basic/process-util.c
+index 1b96d3ca8543..c97185215847 100644
+--- a/src/basic/process-util.c
++++ b/src/basic/process-util.c
+@@ -221,9 +221,12 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
+                         return -ENOMEM;
+ 
+                 /* Drop trailing empty strings. See issue #21186. */
+-                STRV_FOREACH_BACKWARDS(p, args)
+-                        if (isempty(*p))
+-                                *p = mfree(*p);
++                STRV_FOREACH_BACKWARDS(p, args) {
++                        if (!isempty(*p))
++                                break;
++
++                        *p = mfree(*p);
++                }
+ 
+                 ans = quote_command_line(args, shflags);
+                 if (!ans)
diff --git a/22426-fb.patch b/22426-fb.patch
deleted file mode 100644
index 41310df..0000000
--- a/22426-fb.patch
+++ /dev/null
@@ -1,580 +0,0 @@
-From 3dbc067d326c600a92822037118961641fc76575 Mon Sep 17 00:00:00 2001
-From: Pasha Vorobyev <plv@fb.com>
-Date: Fri, 4 Feb 2022 11:49:46 -0800
-Subject: [PATCH] MemoryZSwapMax directive to configure new memory.zswap.max
- cgroup file
-
----
- man/org.freedesktop.systemd1.xml              | 36 +++++++++++++++++++
- src/basic/cgroup-util.c                       | 36 +++++++++++++++++++
- src/basic/cgroup-util.h                       |  2 ++
- src/core/cgroup.c                             | 17 +++++++--
- src/core/cgroup.h                             |  1 +
- src/core/dbus-cgroup.c                        |  8 +++++
- src/core/load-fragment-gperf.gperf.in         |  1 +
- src/core/load-fragment.c                      |  4 ++-
- src/shared/bus-print-properties.c             |  2 +-
- src/shared/bus-unit-util.c                    |  1 +
- src/systemctl/systemctl-show.c                |  8 +++++
- .../fuzz-unit-file/directives-all.service     |  1 +
- test/fuzz/fuzz-unit-file/directives.mount     |  1 +
- test/fuzz/fuzz-unit-file/directives.scope     |  1 +
- test/fuzz/fuzz-unit-file/directives.service   |  1 +
- test/fuzz/fuzz-unit-file/directives.slice     |  1 +
- test/fuzz/fuzz-unit-file/directives.socket    |  1 +
- test/fuzz/fuzz-unit-file/directives.swap      |  1 +
- 18 files changed, 118 insertions(+), 5 deletions(-)
-
-diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
-index c14c5b6601..cc37de4fb4 100644
---- a/man/org.freedesktop.systemd1.xml
-+++ b/man/org.freedesktop.systemd1.xml
-@@ -2493,6 +2493,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -3030,6 +3032,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -3594,6 +3598,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-@@ -4293,6 +4299,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -4858,6 +4866,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -5420,6 +5430,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-@@ -6016,6 +6028,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -6509,6 +6523,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -6989,6 +7005,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-@@ -7706,6 +7724,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -8185,6 +8205,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -8651,6 +8673,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-@@ -9221,6 +9245,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -9364,6 +9390,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -9514,6 +9542,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-@@ -9684,6 +9714,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemorySwapMax = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-+      readonly t MemoryZSwapMax = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly t MemoryLimit = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-       readonly s DevicePolicy = '...';
-@@ -9843,6 +9875,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
- 
-     <!--property MemorySwapMax is not documented!-->
- 
-+    <!--property MemoryZSwapMax is not documented!-->
-+
-     <!--property MemoryLimit is not documented!-->
- 
-     <!--property DevicePolicy is not documented!-->
-@@ -10019,6 +10053,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
-diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
-index 1ff6160dc8..00b1e71520 100644
---- a/src/basic/cgroup-util.c
-+++ b/src/basic/cgroup-util.c
-@@ -160,6 +160,42 @@ bool cg_freezer_supported(void) {
-         return supported;
- }
- 
-+bool cg_kill_supported(void) {
-+        static thread_local int supported = -1;
-+
-+        if (supported >= 0)
-+                return supported;
-+
-+        if (cg_all_unified() <= 0)
-+                supported = false;
-+        else if (access("/sys/fs/cgroup/init.scope/cgroup.kill", F_OK) < 0) {
-+                if (errno != ENOENT)
-+                        log_debug_errno(errno, "Failed to check if cgroup.kill is available, assuming not: %m");
-+                supported = false;
-+        } else
-+                supported = true;
-+
-+        return supported;
-+}
-+
-+bool cg_zswap_supported(void) {
-+        static thread_local int supported = -1;
-+
-+        if (supported >= 0)
-+                return supported;
-+
-+        if (cg_all_unified() <= 0)
-+                supported = false;
-+        else if (access("/sys/fs/cgroup/init.scope/memory.zswap.max", F_OK) < 0) {
-+                if (errno != ENOENT)
-+                        log_debug_errno(errno, "Failed to check if cgroup memory.zswap.max is available, assuming not: %m");
-+                supported = false;
-+        } else
-+                supported = true;
-+
-+        return supported;
-+}
-+
- int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
-         _cleanup_free_ char *fs = NULL;
-         int r;
-diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
-index ce2f4c6589..8ea94b8870 100644
---- a/src/basic/cgroup-util.h
-+++ b/src/basic/cgroup-util.h
-@@ -272,6 +272,8 @@ int cg_kernel_controllers(Set **controllers);
- 
- bool cg_ns_supported(void);
- bool cg_freezer_supported(void);
-+bool cg_kill_supported(void);
-+bool cg_zswap_supported(void);
- 
- int cg_all_unified(void);
- int cg_hybrid_unified(void);
-diff --git a/src/core/cgroup.c b/src/core/cgroup.c
-index 5c07aa71d1..4a0aa65037 100644
---- a/src/core/cgroup.c
-+++ b/src/core/cgroup.c
-@@ -123,6 +123,7 @@ void cgroup_context_init(CGroupContext *c) {
-                 .memory_high = CGROUP_LIMIT_MAX,
-                 .memory_max = CGROUP_LIMIT_MAX,
-                 .memory_swap_max = CGROUP_LIMIT_MAX,
-+                .memory_zswap_max = CGROUP_LIMIT_MAX,
- 
-                 .memory_limit = CGROUP_LIMIT_MAX,
- 
-@@ -322,6 +323,9 @@ static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_
-         } else if (streq(property_name, "MemorySwapMax")) {
-                 unit_value = c->memory_swap_max;
-                 file = "memory.swap.max";
-+        } else if (streq(property_name, "MemoryZSwapMax")) {
-+                unit_value = c->memory_zswap_max;
-+                file = "memory.zswap.max";
-         } else
-                 return -EINVAL;
- 
-@@ -364,9 +368,10 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u,
- 
-         /* memory.swap.max is special in that it relies on CONFIG_MEMCG_SWAP (and the default swapaccount=1).
-          * In the absence of reliably being able to detect whether memcg swap support is available or not,
--         * only complain if the error is not ENOENT. */
-+         * only complain if the error is not ENOENT. This is similarly the case for memory.zswap.max relying on CONFIG_ZSWAP. */
-         if (r > 0 || IN_SET(r, -ENODATA, -EOWNERDEAD) ||
--            (r == -ENOENT && streq(property_name, "MemorySwapMax"))) {
-+            (r == -ENOENT && (streq(property_name, "MemorySwapMax") ||
-+                              streq(property_name, "MemoryZSwapMax")))) {
-                 buf[0] = 0;
-                 return buf;
-         }
-@@ -441,6 +446,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
-                 "%sMemoryHigh: %" PRIu64 "%s\n"
-                 "%sMemoryMax: %" PRIu64 "%s\n"
-                 "%sMemorySwapMax: %" PRIu64 "%s\n"
-+                "%sMemoryZSwapMax: %" PRIu64 "%s\n"
-                 "%sMemoryLimit: %" PRIu64 "\n"
-                 "%sTasksMax: %" PRIu64 "\n"
-                 "%sDevicePolicy: %s\n"
-@@ -475,6 +481,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
-                 prefix, c->memory_high, format_cgroup_memory_limit_comparison(cdc, sizeof(cdc), u, "MemoryHigh"),
-                 prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"),
-                 prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
-+                prefix, c->memory_zswap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemoryZSwapMax"),
-                 prefix, c->memory_limit,
-                 prefix, tasks_max_resolve(&c->tasks_max),
-                 prefix, cgroup_device_policy_to_string(c->device_policy),
-@@ -1075,7 +1082,7 @@ static bool unit_has_unified_memory_config(Unit *u) {
- 
-         return unit_get_ancestor_memory_min(u) > 0 || unit_get_ancestor_memory_low(u) > 0 ||
-                c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX ||
--               c->memory_swap_max != CGROUP_LIMIT_MAX;
-+               c->memory_swap_max != CGROUP_LIMIT_MAX || c->memory_zswap_max != CGROUP_LIMIT_MAX;
- }
- 
- static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) {
-@@ -1442,10 +1449,12 @@ static void cgroup_context_apply(
- 
-                 if (cg_all_unified() > 0) {
-                         uint64_t max, swap_max = CGROUP_LIMIT_MAX;
-+                        uint64_t zswap_max = CGROUP_LIMIT_MAX;
- 
-                         if (unit_has_unified_memory_config(u)) {
-                                 max = c->memory_max;
-                                 swap_max = c->memory_swap_max;
-+                                zswap_max = c->memory_zswap_max;
-                         } else {
-                                 max = c->memory_limit;
- 
-@@ -1458,6 +1467,8 @@ static void cgroup_context_apply(
-                         cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high);
-                         cgroup_apply_unified_memory_limit(u, "memory.max", max);
-                         cgroup_apply_unified_memory_limit(u, "memory.swap.max", swap_max);
-+                        if (cg_zswap_supported())
-+                                cgroup_apply_unified_memory_limit(u, "memory.zswap.max", zswap_max);
- 
-                         (void) set_attribute_and_warn(u, "memory", "memory.oom.group", one_zero(c->memory_oom_group));
- 
-diff --git a/src/core/cgroup.h b/src/core/cgroup.h
-index 3f8cad899d..d40ac0fadc 100644
---- a/src/core/cgroup.h
-+++ b/src/core/cgroup.h
-@@ -147,6 +147,7 @@ struct CGroupContext {
-         uint64_t memory_high;
-         uint64_t memory_max;
-         uint64_t memory_swap_max;
-+        uint64_t memory_zswap_max;
- 
-         bool default_memory_min_set;
-         bool default_memory_low_set;
-diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
-index 84c3caf3a5..e57ceff6f4 100644
---- a/src/core/dbus-cgroup.c
-+++ b/src/core/dbus-cgroup.c
-@@ -439,6 +439,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
-         SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
-         SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0),
-         SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0),
-+        SD_BUS_PROPERTY("MemoryZSwapMax", "t", NULL, offsetof(CGroupContext, memory_zswap_max), 0),
-         SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
-         SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
-         SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
-@@ -860,6 +861,7 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEI
- BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
- BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
- BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
-+BUS_DEFINE_SET_CGROUP_LIMIT(zswap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
- REENABLE_WARNING;
- 
- static int bus_cgroup_set_tasks_max(
-@@ -1019,6 +1021,9 @@ int bus_cgroup_set_property(
-         if (streq(name, "MemorySwapMax"))
-                 return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error);
- 
-+        if (streq(name, "MemoryZSwapMax"))
-+                return bus_cgroup_set_zswap(u, name, &c->memory_zswap_max, message, flags, error);
-+
-         if (streq(name, "MemoryMax"))
-                 return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error);
- 
-@@ -1059,6 +1064,9 @@ int bus_cgroup_set_property(
-         if (streq(name, "MemorySwapMaxScale"))
-                 return bus_cgroup_set_swap_scale(u, name, &c->memory_swap_max, message, flags, error);
- 
-+        if (streq(name, "MemoryZSwapMaxScale"))
-+                return bus_cgroup_set_zswap_scale(u, name, &c->memory_zswap_max, message, flags, error);
-+
-         if (streq(name, "MemoryMaxScale"))
-                 return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error);
- 
-diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
-index 42441eab6e..27860fb973 100644
---- a/src/core/load-fragment-gperf.gperf.in
-+++ b/src/core/load-fragment-gperf.gperf.in
-@@ -196,6 +196,7 @@
- {{type}}.MemoryHigh,                       config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
- {{type}}.MemoryMax,                        config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
- {{type}}.MemorySwapMax,                    config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
-+{{type}}.MemoryZSwapMax,                   config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
- {{type}}.MemoryLimit,                      config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
- {{type}}.DeviceAllow,                      config_parse_device_allow,                   0,                                  offsetof({{type}}, cgroup_context)
- {{type}}.DevicePolicy,                     config_parse_device_policy,                  0,                                  offsetof({{type}}, cgroup_context.device_policy)
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
-index a068fdf313..b64e64d90f 100644
---- a/src/core/load-fragment.c
-+++ b/src/core/load-fragment.c
-@@ -3690,7 +3690,7 @@ int config_parse_memory_limit(
-                         bytes = physical_memory_scale(r, 10000U);
- 
-                 if (bytes >= UINT64_MAX ||
--                    (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) {
-+                    (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryZSwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) {
-                         log_syntax(unit, LOG_WARNING, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue);
-                         return 0;
-                 }
-@@ -3714,6 +3714,8 @@ int config_parse_memory_limit(
-                 c->memory_max = bytes;
-         else if (streq(lvalue, "MemorySwapMax"))
-                 c->memory_swap_max = bytes;
-+        else if (streq(lvalue, "MemoryZSwapMax"))
-+                c->memory_zswap_max = bytes;
-         else if (streq(lvalue, "MemoryLimit"))
-                 c->memory_limit = bytes;
-         else
-diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c
-index b45921943a..31c2e3cd35 100644
---- a/src/shared/bus-print-properties.c
-+++ b/src/shared/bus-print-properties.c
-@@ -165,7 +165,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
- 
-                         bus_print_property_value(name, expected_value, flags, "[not set]");
- 
--                else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "MemoryAvailable") && u == CGROUP_LIMIT_MAX) ||
-+                else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryZSwapMax", "MemoryLimit", "MemoryAvailable") && u == CGROUP_LIMIT_MAX) ||
-                          (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == UINT64_MAX) ||
-                          (startswith(name, "Limit") && u == UINT64_MAX) ||
-                          (startswith(name, "DefaultLimit") && u == UINT64_MAX))
-diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
-index d3a5b25d18..f89b6e7428 100644
---- a/src/shared/bus-unit-util.c
-+++ b/src/shared/bus-unit-util.c
-@@ -516,6 +516,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
-                               "MemoryHigh",
-                               "MemoryMax",
-                               "MemorySwapMax",
-+                              "MemoryZSwapMax",
-                               "MemoryLimit",
-                               "TasksMax")) {
- 
-diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c
-index 1f524626bf..2bba11936e 100644
---- a/src/systemctl/systemctl-show.c
-+++ b/src/systemctl/systemctl-show.c
-@@ -247,6 +247,7 @@ typedef struct UnitStatusInfo {
-         uint64_t memory_high;
-         uint64_t memory_max;
-         uint64_t memory_swap_max;
-+        uint64_t memory_zswap_max;
-         uint64_t memory_limit;
-         uint64_t memory_available;
-         uint64_t cpu_usage_nsec;
-@@ -684,6 +685,7 @@ static void print_status_info(
-                 if (i->memory_min > 0 || i->memory_low > 0 ||
-                     i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX ||
-                     i->memory_swap_max != CGROUP_LIMIT_MAX ||
-+                    i->memory_zswap_max != CGROUP_LIMIT_MAX ||
-                     i->memory_available != CGROUP_LIMIT_MAX ||
-                     i->memory_limit != CGROUP_LIMIT_MAX) {
-                         const char *prefix = "";
-@@ -709,6 +711,10 @@ static void print_status_info(
-                                 printf("%sswap max: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_swap_max));
-                                 prefix = " ";
-                         }
-+                        if (i->memory_zswap_max != CGROUP_LIMIT_MAX) {
-+                                printf("%szswap max: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_zswap_max));
-+                                prefix = " ";
-+                        }
-                         if (i->memory_limit != CGROUP_LIMIT_MAX) {
-                                 printf("%slimit: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_limit));
-                                 prefix = " ";
-@@ -1850,6 +1856,7 @@ static int show_one(
-                 { "MemoryHigh",                     "t",               NULL,           offsetof(UnitStatusInfo, memory_high)                       },
-                 { "MemoryMax",                      "t",               NULL,           offsetof(UnitStatusInfo, memory_max)                        },
-                 { "MemorySwapMax",                  "t",               NULL,           offsetof(UnitStatusInfo, memory_swap_max)                   },
-+                { "MemoryZSwapMax",                 "t",               NULL,           offsetof(UnitStatusInfo, memory_zswap_max)                  },
-                 { "MemoryLimit",                    "t",               NULL,           offsetof(UnitStatusInfo, memory_limit)                      },
-                 { "CPUUsageNSec",                   "t",               NULL,           offsetof(UnitStatusInfo, cpu_usage_nsec)                    },
-                 { "TasksCurrent",                   "t",               NULL,           offsetof(UnitStatusInfo, tasks_current)                     },
-@@ -1884,6 +1891,7 @@ static int show_one(
-                 .memory_high = CGROUP_LIMIT_MAX,
-                 .memory_max = CGROUP_LIMIT_MAX,
-                 .memory_swap_max = CGROUP_LIMIT_MAX,
-+                .memory_zswap_max = CGROUP_LIMIT_MAX,
-                 .memory_limit = UINT64_MAX,
-                 .memory_available = CGROUP_LIMIT_MAX,
-                 .cpu_usage_nsec = UINT64_MAX,
-diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service
-index 3039d1c0cd..81ffe4fc86 100644
---- a/test/fuzz/fuzz-unit-file/directives-all.service
-+++ b/test/fuzz/fuzz-unit-file/directives-all.service
-@@ -152,6 +152,7 @@ MemoryLimit=
- MemoryLow=
- MemoryMax=
- MemorySwapMax=
-+MemoryZSwapMax=
- MessageQueueMaxMessages=
- MessageQueueMessageSize=
- MountAPIVFS=
-diff --git a/test/fuzz/fuzz-unit-file/directives.mount b/test/fuzz/fuzz-unit-file/directives.mount
-index 451f291988..ba5d03cc4b 100644
---- a/test/fuzz/fuzz-unit-file/directives.mount
-+++ b/test/fuzz/fuzz-unit-file/directives.mount
-@@ -103,6 +103,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- MountAPIVFS=
- MountFlags=
- MountImages=
-diff --git a/test/fuzz/fuzz-unit-file/directives.scope b/test/fuzz/fuzz-unit-file/directives.scope
-index 7e69cf816b..12e3f02b9b 100644
---- a/test/fuzz/fuzz-unit-file/directives.scope
-+++ b/test/fuzz/fuzz-unit-file/directives.scope
-@@ -46,6 +46,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- NetClass=
- RestartKillSignal=
- RuntimeMaxSec=
-diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
-index de7d2c7daf..b27b100f1a 100644
---- a/test/fuzz/fuzz-unit-file/directives.service
-+++ b/test/fuzz/fuzz-unit-file/directives.service
-@@ -225,6 +225,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- MountAPIVFS=
- MountFlags=
- MountImages=
-diff --git a/test/fuzz/fuzz-unit-file/directives.slice b/test/fuzz/fuzz-unit-file/directives.slice
-index 789ac8f0db..0004d4dfd4 100644
---- a/test/fuzz/fuzz-unit-file/directives.slice
-+++ b/test/fuzz/fuzz-unit-file/directives.slice
-@@ -43,6 +43,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- NetClass=
- Slice=
- SocketBindAllow=
-diff --git a/test/fuzz/fuzz-unit-file/directives.socket b/test/fuzz/fuzz-unit-file/directives.socket
-index 11f589e22c..02e0349009 100644
---- a/test/fuzz/fuzz-unit-file/directives.socket
-+++ b/test/fuzz/fuzz-unit-file/directives.socket
-@@ -131,6 +131,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- MessageQueueMaxMessages=
- MessageQueueMessageSize=
- MountAPIVFS=
-diff --git a/test/fuzz/fuzz-unit-file/directives.swap b/test/fuzz/fuzz-unit-file/directives.swap
-index 582a136531..4536b2a606 100644
---- a/test/fuzz/fuzz-unit-file/directives.swap
-+++ b/test/fuzz/fuzz-unit-file/directives.swap
-@@ -100,6 +100,7 @@ MemoryLow=
- MemoryMax=
- MemoryMin=
- MemorySwapMax=
-+MemoryZSwapMax=
- MountAPIVFS=
- MountFlags=
- MountImages=
--- 
-2.34.1
-
diff --git a/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch b/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch
deleted file mode 100644
index 6b148ad..0000000
--- a/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 1035e36675e10522824476c9084ff1001039c054 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Fri, 1 Oct 2021 09:22:18 +0900
-Subject: [PATCH] network: drop and warn duplicated Address= settings
-
-Fixes #20891.
----
- src/network/networkd-address.c | 43 +++++++++++++++++++++++++++++++---
- src/network/networkd-address.h |  2 +-
- src/network/networkd-network.c |  6 ++++-
- 3 files changed, 46 insertions(+), 5 deletions(-)
-
-diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
-index 7b221516d7..e1bc6aa474 100644
---- a/src/network/networkd-address.c
-+++ b/src/network/networkd-address.c
-@@ -304,6 +304,12 @@ bool address_equal(const Address *a1, const Address *a2) {
-         return address_compare_func(a1, a2) == 0;
- }
- 
-+DEFINE_PRIVATE_HASH_OPS(
-+        address_hash_ops_new,
-+        Address,
-+        address_hash_func,
-+        address_compare_func);
-+
- int address_dup(const Address *src, Address **ret) {
-         _cleanup_(address_freep) Address *dest = NULL;
-         int r;
-@@ -1988,12 +1994,43 @@ static int address_section_verify(Address *address) {
-         return 0;
- }
- 
--void network_drop_invalid_addresses(Network *network) {
-+int network_drop_invalid_addresses(Network *network) {
-+        _cleanup_set_free_ Set *addresses = NULL;
-         Address *address;
-+        int r;
- 
-         assert(network);
- 
--        ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
--                if (address_section_verify(address) < 0)
-+        ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) {
-+                Address *dup;
-+
-+                if (address_section_verify(address) < 0) {
-+                        /* Drop invalid [Address] sections or Address= settings in [Network].
-+                         * Note that address_free() will drop the address from addresses_by_section. */
-                         address_free(address);
-+                        continue;
-+                }
-+
-+                /* Always use the setting specified later. So, remove the previously assigned setting. */
-+                dup = set_remove(addresses, address);
-+                if (dup) {
-+                        _cleanup_free_ char *buf = NULL;
-+
-+                        (void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buf);
-+                        log_warning("%s: Duplicated address %s is specified at line %u and %u, "
-+                                    "dropping the address setting specified at line %u.",
-+                                    dup->section->filename, strna(buf), address->section->line,
-+                                    dup->section->line, dup->section->line);
-+                        /* address_free() will drop the address from addresses_by_section. */
-+                        address_free(dup);
-+                }
-+
-+                /* Do not use address_hash_ops_free here. Otherwise, all address settings will be freed. */
-+                r = set_ensure_put(&addresses, &address_hash_ops_new, address);
-+                if (r < 0)
-+                        return log_oom();
-+                assert(r > 0);
-+        }
-+
-+        return 0;
- }
-diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
-index ff3d46abdd..55d22ad221 100644
---- a/src/network/networkd-address.h
-+++ b/src/network/networkd-address.h
-@@ -85,7 +85,7 @@ int request_process_address(Request *req);
- 
- int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
- 
--void network_drop_invalid_addresses(Network *network);
-+int network_drop_invalid_addresses(Network *network);
- 
- void address_hash_func(const Address *a, struct siphash *state);
- int address_compare_func(const Address *a1, const Address *a2);
-diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
-index 2a864a38b1..920f7851ba 100644
---- a/src/network/networkd-network.c
-+++ b/src/network/networkd-network.c
-@@ -119,6 +119,8 @@ static int network_resolve_stacked_netdevs(Network *network) {
- }
- 
- int network_verify(Network *network) {
-+        int r;
-+
-         assert(network);
-         assert(network->filename);
- 
-@@ -252,7 +254,9 @@ int network_verify(Network *network) {
-                 network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses);
-         }
- 
--        network_drop_invalid_addresses(network);
-+        r = network_drop_invalid_addresses(network);
-+        if (r < 0)
-+                return r;
-         network_drop_invalid_routes(network);
-         network_drop_invalid_nexthops(network);
-         network_drop_invalid_bridge_fdb_entries(network);
--- 
-2.31.1
-
diff --git a/README.build-in-place b/README.build-in-place
index 8b66077..9d68330 100644
--- a/README.build-in-place
+++ b/README.build-in-place
@@ -1,7 +1,7 @@
 == Building systemd rpms for local development using rpmbuild --build-in-place ==
 
 This approach is based on https://github.com/filbranden/git-rpmbuild
-and filbranden's talk during ASG2019 [https://cfp.all-systems-go.io/ASG2019/talk/JM7GDN/].
+and filbranden's talk during ASG2019 [https://www.youtube.com/watch?v=fVM1kJrymRM].
 
 ```
 git clone https://github.com/systemd/systemd
diff --git a/bbe53713455be38c0a587626439fd171f28c77fc.patch b/bbe53713455be38c0a587626439fd171f28c77fc.patch
new file mode 100644
index 0000000..9f5bd29
--- /dev/null
+++ b/bbe53713455be38c0a587626439fd171f28c77fc.patch
@@ -0,0 +1,65 @@
+From bbe53713455be38c0a587626439fd171f28c77fc Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Sun, 30 Jan 2022 23:40:05 +0100
+Subject: [PATCH] basic: update CIFS magic
+
+Kernel commit dea2903719283c156b53741126228c4a1b40440f exposed (and
+renamed) CIFS_MAGIC_NUMBER as CIFS_SUPER_MAGIC along with
+SMB2_SUPER_MAGIC.
+
+This fixes the following build fail on current Fedora Rawhide:
+```
+../src/basic/meson.build:389:8: ERROR: Problem encountered: found unknown filesystem(s) defined in kernel headers:
+
+Filesystem found in kernel header but not in filesystems-gperf.gperf: CIFS_SUPER_MAGIC
+Filesystem found in kernel header but not in filesystems-gperf.gperf: SMB2_SUPER_MAGIC
+```
+---
+ src/basic/filesystems-gperf.gperf |  4 ++--
+ src/basic/missing_magic.h         | 11 ++++++++---
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/src/basic/filesystems-gperf.gperf b/src/basic/filesystems-gperf.gperf
+index 08c8c445105a..e8c5357f9146 100644
+--- a/src/basic/filesystems-gperf.gperf
++++ b/src/basic/filesystems-gperf.gperf
+@@ -40,7 +40,7 @@ ceph,            {CEPH_SUPER_MAGIC}
+ cgroup2,         {CGROUP2_SUPER_MAGIC}
+ # note that the cgroupfs magic got reassigned from cpuset
+ cgroup,          {CGROUP_SUPER_MAGIC}
+-cifs,            {CIFS_MAGIC_NUMBER}
++cifs,            {CIFS_SUPER_MAGIC, SMB2_SUPER_MAGIC}
+ coda,            {CODA_SUPER_MAGIC}
+ configfs,        {CONFIGFS_MAGIC}
+ cramfs,          {CRAMFS_MAGIC}
+@@ -109,7 +109,7 @@ selinuxfs,       {SELINUX_MAGIC}
+ shiftfs,         {SHIFTFS_MAGIC}
+ smackfs,         {SMACK_MAGIC}
+ # smb3 is an alias for cifs
+-smb3,            {CIFS_MAGIC_NUMBER}
++smb3,            {CIFS_SUPER_MAGIC}
+ # smbfs was removed from the kernel in 2010, the magic remains
+ smbfs,           {SMB_SUPER_MAGIC}
+ sockfs,          {SOCKFS_MAGIC}
+diff --git a/src/basic/missing_magic.h b/src/basic/missing_magic.h
+index 7d9320bb6dc9..c104fcfba315 100644
+--- a/src/basic/missing_magic.h
++++ b/src/basic/missing_magic.h
+@@ -38,9 +38,14 @@
+ #define XFS_SB_MAGIC 0x58465342
+ #endif
+ 
+-/* Not exposed yet. Defined at fs/cifs/cifsglob.h */
+-#ifndef CIFS_MAGIC_NUMBER
+-#define CIFS_MAGIC_NUMBER 0xFF534D42
++/* dea2903719283c156b53741126228c4a1b40440f (5.17) */
++#ifndef CIFS_SUPER_MAGIC
++#define CIFS_SUPER_MAGIC 0xFF534D42
++#endif
++
++/* dea2903719283c156b53741126228c4a1b40440f (5.17) */
++#ifndef SMB2_SUPER_MAGIC
++#define SMB2_SUPER_MAGIC 0xFE534D42
+ #endif
+ 
+ /* 257f871993474e2bde6c497b54022c362cf398e1 (4.5) */
diff --git a/libfdisk_version_for_centos.patch b/libfdisk_version_for_centos.patch
deleted file mode 100644
index 1a8535b..0000000
--- a/libfdisk_version_for_centos.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 69443affcaa711a9a3355994458542d3732631a5 Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Tue, 30 Nov 2021 12:08:50 -0800
-Subject: [PATCH] Re-enable repart if libfdisk ver. has range fix
-
----
- meson.build | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/meson.build b/meson.build
-index 6263e7c0fc..35e6c4f376 100644
---- a/meson.build
-+++ b/meson.build
-@@ -1011,7 +1011,7 @@ libmount = dependency('mount',
- want_libfdisk = get_option('fdisk')
- if want_libfdisk != 'false' and not skip_deps
-         libfdisk = dependency('fdisk',
--                              version : '>= 2.33',
-+                              version : '>= 2.32.1',
-                               required : want_libfdisk == 'true')
-         have = libfdisk.found()
- else
---
-2.31.1
-
diff --git a/sources b/sources
index 6d600ac..dacaeaf 100644
--- a/sources
+++ b/sources
@@ -1 +1,2 @@
-SHA512 (systemd-249.4.tar.gz) = 5b9ec28102538bc3dcb632ee16389ff20dccf4b723186f6ae2da119a1809d84db0d8bcecf9b75c5e2da8427f5543e1da281bbed1a154e529d8a82ea5128c465c
+SHA512 (systemd-hs-250.3.tar.gz) = 36ce9b321f7533d7385d3e8fa8d42c83ccf78521e85c6381f3f7b023fcdc5bdd99a17cfee81bd7669d32753298b783aeafc8608973ad2801a75151b67ef2fe46
+SHA512 (systemd-hs+fb-250.3.tar.gz) = 8bdaf837ae04ec5dfb06d0d8e06cc596938cfccb85ffec224d31c20514a1bcc50de84d74efdc97a21a368d50f1570b5abecadedcd95f35c7224a5def9f3cd851
diff --git a/split-files.py b/split-files.py
index f883f73..9614c07 100644
--- a/split-files.py
+++ b/split-files.py
@@ -85,9 +85,11 @@ for file in files(buildroot):
         o = o_networkd
     elif '.so.' in n:
         o = o_libs
+
     elif re.search(r'''udev(?!\.pc)|
                        hwdb|
                        bootctl|
+                       boot-update|
                        sd-boot|systemd-boot\.|loader.conf|
                        bless-boot|
                        boot-system-token|
@@ -98,7 +100,9 @@ for file in files(buildroot):
                        random-seed|
                        modules-load|
                        timesync|
+                       crypttab|
                        cryptsetup|
+                       libcryptsetup-token-systemd|
                        kmod|
                        quota|
                        pstore|
@@ -110,25 +114,35 @@ for file in files(buildroot):
                        repart|
                        gpt-auto|
                        volatile-root|
-                       verity-setup|
+                       veritysetup|
+                       integritysetup|
+                       integritytab|
                        remount-fs|
                        /boot$|
                        /boot/efi|
                        /kernel/|
                        /kernel$|
-                       /modprobe.d
-    ''', n, re.X):
+                       /modprobe.d|
+                       binfmt|
+                       sysctl|
+                       coredump|
+                       homed|home1|
+                       portabled|portable1
+    ''', n, re.X):     # coredumpctl, homectl, portablectl are included in the main package because
+                       # they can be used to interact with remote daemons. Also, the user could be
+                       # confused if those user-facing binaries are not available.
         o = o_udev
-    elif re.search(r'''resolvectl|
-                       resolved|
+
+    elif re.search(r'''resolved|resolve1|
                        systemd-resolve|
                        resolvconf|
-                       resolve1\.
-    ''', n, re.X):
-        # keep only nss-resolve in systemd
+                       systemd\.(positive|negative)
+    ''', n, re.X):     # resolvectl and nss-resolve are in the main package.
         o = o_resolve
+
     elif re.search(r'10-oomd-.*defaults.conf|lib/systemd/oomd.conf.d', n, re.X):
         o = o_oomd_defaults
+
     elif n.endswith('.standalone'):
         if 'tmpfiles' in n:
             o = o_standalone_tmpfiles
@@ -136,6 +150,7 @@ for file in files(buildroot):
             o = o_standalone_sysusers
         else:
             assert False, 'Found .standalone not belonging to known packages'
+
     else:
         o = o_rest
 
diff --git a/systemd-user b/systemd-user
index 2725df9..c4c427f 100644
--- a/systemd-user
+++ b/systemd-user
@@ -7,4 +7,5 @@ account  include system-auth
 session  required pam_selinux.so close
 session  required pam_selinux.so nottys open
 session  required pam_loginuid.so
+session  required pam_namespace.so
 session  include system-auth
diff --git a/systemd.spec b/systemd.spec
index 3f84851..7fb498e 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -3,6 +3,12 @@
 
 %global stable 1
 
+%if 0%{?facebook}
+%global hs_commit c389d4c9c7a1bbc5f125c63a430d9475d672ddc3
+%else
+%global hs_commit c47889a351e56393bfb267d8a7a5655b8a86dbfd
+%endif
+
 # We ship a .pc file but don't want to have a dep on pkg-config. We
 # strip the automatically generated dep here and instead co-own the
 # directory.
@@ -17,8 +23,8 @@
 %global elf_suffix ()%{elf_bits}
 %endif
 
-# Bootstrap may be needed to break intercircular dependencies with
-# cryptsetup, e.g. when re-building cryptsetup on a json-c SONAME-bump.
+# Bootstrap may be needed to break circular dependencies with cryptsetup,
+# e.g. when re-building cryptsetup on a json-c SONAME-bump.
 %bcond_with    bootstrap
 %bcond_without tests
 %bcond_without lto
@@ -33,33 +39,23 @@
 %bcond_without selinux
 %endif
 
-# Remove this when the macro exists in CentOS
-%global version_no_tilde %(c=%{version}; echo ${c}|tr '~' '-')
-
 Name:           systemd
-Url:            https://www.freedesktop.org/wiki/Software/systemd
+Url:            https://pagure.io/centos-sig-hyperscale/systemd
 %if %{without inplace}
-Version:        249.4
-Release:        2.13%{?dist}
+Version:        250.3
+Release:        6.1%{?dist}
 %else
 # determine the build information from local checkout
 Version:        %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/')
-Release:        1
+Release:        2
 %endif
+
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        System and Service Manager
 
 # download tarballs with "spectool -g systemd.spec"
-%if %{defined commit}
-Source0:        https://github.com/systemd/systemd%{?stable:-stable}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz
-%else
-%if 0%{?stable}
-Source0:        https://github.com/systemd/systemd-stable/archive/v%{version_no_tilde}/%{name}-%{version_no_tilde}.tar.gz
-%else
-Source0:        https://github.com/systemd/systemd/archive/v%{version_no_tilde}/%{name}-%{version_no_tilde}.tar.gz
-%endif
-%endif
+Source0:        %{url}/archive/%{hs_commit}/%{name}-hs%{?facebook:+fb}-%{version}.tar.gz
 # This file must be available before %%prep.
 # It is generated during systemd build and can be found in build/src/core/.
 Source1:        triggers.systemd
@@ -71,7 +67,6 @@ Source4:        yum-protect-systemd.conf
 
 Source9:        20-yama-ptrace.conf
 Source10:       systemd-udev-trigger-no-reload.conf
-Source11:       20-grubby.install
 Source12:       systemd-user
 Source13:       libsystemd-shared.abignore
 
@@ -92,7 +87,7 @@ Source102:      systemd_hs.if
 %if 0
 GIT_DIR=../../src/systemd/.git git format-patch-ab --no-signature -M -N v235..v235-stable
 i=1; for j in 00*patch; do printf "Patch%04d:      %s\n" $i $j; i=$((i+1));done|xclip
-GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[67]* hwdb/parse_hwdb.py > hwdb.patch
+GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[67]* hwdb/parse_hwdb.py >hwdb.patch
 %endif
 
 # Backports of patches from upstream (0000–0499)
@@ -100,66 +95,12 @@ GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[
 # Any patches which are "in preparation" upstream should be listed
 # here, rather than in the next section. Packit CI will drop any
 # patches in this range before applying upstream pull requests.
+Patch:          https://github.com/systemd/systemd/commit/bbe53713455be38c0a587626439fd171f28c77fc.patch
 
-%if 0%{?facebook}
-Patch0001:      0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch
-Patch0002:      0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch
-Patch0003:      0003-rpm-call-needs-restart-in-parallel.patch
-Patch0004:      0004-rpm-restart-user-services-at-the-end-of-the-transact.patch
-Patch0005:      0005-update-helper-also-add-user-reexec-verb.patch
-
-# PR 18621: FB variant of quieting "proc: Bad value for 'hidepid'" messages
-Patch0006:      18621-fb.patch
-%else
-# PR 18621: Quiet "proc: Bad value for 'hidepid'" messages
-Patch0006:      https://github.com/systemd/systemd/pull/18621.patch
-%endif
-
-# PRs to support additional systemd.network and systemd.link features
-Patch0007:      https://github.com/systemd/systemd/pull/20743.patch
-Patch0008:      https://github.com/systemd/systemd/pull/20458.patch
-Patch0009:      https://github.com/systemd/systemd/pull/20472.patch
-Patch0010:      https://github.com/systemd/systemd/pull/20477.patch
-Patch0011:      https://github.com/systemd/systemd/pull/20484.patch
-Patch0012:      https://github.com/systemd/systemd/pull/20489.patch
-Patch0013:      https://github.com/systemd/systemd/pull/20450.patch
-Patch0014:      https://github.com/systemd/systemd/pull/20541.patch
-Patch0015:      https://github.com/systemd/systemd/pull/20729.patch
-Patch0016:      https://github.com/systemd/systemd/pull/20828.patch
-# Part of PR #20892; it was difficult to backport the whole PR
-Patch0017:      50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch
-
-# PR 20875: allow verifying hidden (dot) files again
-Patch0018:      https://github.com/systemd/systemd/pull/20875.patch
-
-# PR 20978: serialize bpf device programs across reloads/reexecs
-Patch0019:      https://github.com/systemd/systemd/pull/20978.patch
-
-# PR 20676: don't rewrite sysctls that are already set
-Patch0020:      20676_cherrypicked.patch
-
-# PR 21221: Fixes non-deterministic Slice= assignments
-Patch0021:      21221.patch
-
-# PR 21241: fix bpf-foreign cgroup controller realization
-Patch0022:      21241.patch
-
-# PR 20695: Sync if_arp.h with Linux 5.14
-Patch0023:      20695.patch
-
-%if 0%{?facebook}
-# PR 22426: MemoryZSwapMax= to configure memory.zswap.max
-Patch0024:      22426-fb.patch
-%endif
-
-# Downstream-only patches (0500–9999)
+# Downstream-only patches (5000–9999)
 
 # https://github.com/systemd/systemd/pull/17050
 Patch0501:      https://github.com/systemd/systemd/pull/17050/commits/f58b96d3e8d1cb0dd3666bc74fa673918b586612.patch
-# Downgrade sysv-generator messages from warning to debug
-Patch0502:      0001-sysv-generator-downgrade-log-warning-about-autogener.patch
-# Update libfdisk dep version to 2.32.1-26 (has the fix for repart tests to pass)
-Patch0503:      libfdisk_version_for_centos.patch
 
 %ifarch %{ix86} x86_64 aarch64
 %global have_gnu_efi 1
@@ -167,10 +108,12 @@ Patch0503:      libfdisk_version_for_centos.patch
 
 BuildRequires:  gcc
 BuildRequires:  gcc-c++
+BuildRequires:  clang
+BuildRequires:  llvm-toolset
 BuildRequires:  coreutils
 BuildRequires:  libcap-devel
 BuildRequires:  libmount-devel
-BuildRequires:  libfdisk-devel >= 2.32.1-26
+BuildRequires:  libfdisk-devel
 BuildRequires:  libpwquality-devel
 BuildRequires:  pam-devel
 BuildRequires:  libselinux-devel
@@ -205,6 +148,8 @@ BuildRequires:  iptables-devel
 BuildRequires:  pkgconfig(tss2-esys)
 BuildRequires:  pkgconfig(tss2-rc)
 BuildRequires:  pkgconfig(tss2-mu)
+BuildRequires:  pkgconfig(libbpf)
+BuildRequires:  bpftool
 BuildRequires:  systemtap-sdt-devel
 BuildRequires:  libxslt
 BuildRequires:  docbook-style-xsl
@@ -233,15 +178,12 @@ BuildRequires:  perl
 BuildRequires:  perl(IPC::SysV)
 
 Requires(post): coreutils
-Requires(post): sed
-Requires(post): acl
 Requires(post): grep
 # systemd-machine-id-setup requires libssl
 Requires(post): openssl-libs
-Requires(pre):  coreutils
 Requires:       dbus >= 1.9.18
 Requires:       %{name}-pam = %{version}-%{release}
-Requires:       (%{name}-rpm-macros = %{version}-%{release} if rpm-build)
+Requires:       %{name}-rpm-macros = %{version}-%{release}
 Requires:       %{name}-libs = %{version}-%{release}
 %{?fedora:Recommends:     %{name}-networkd = %{version}-%{release}}
 %{?fedora:Recommends:     %{name}-resolved = %{version}-%{release}}
@@ -278,26 +220,37 @@ Recommends:     libidn2.so.0(IDN2_0.0.0)%{?elf_bits}
 Recommends:     libpcre2-8.so.0%{?elf_suffix}
 Recommends:     libpwquality.so.1%{?elf_suffix}
 Recommends:     libpwquality.so.1(LIBPWQUALITY_1.0)%{?elf_bits}
+Recommends:     libqrencode.so.4%{?elf_suffix}
 
 %if %{with selinux}
 # Force the SELinux module to be installed
 Requires:       %{name}-selinux = %{version}-%{release}
 %endif
 
+Recommends:     libbpf.so.0%{?elf_suffix}
+Recommends:     libbpf.so.0(LIBBPF_0.4.0)%{?elf_bits}
+
+# used by systemd-coredump and systemd-analyze
+Recommends:     libdw.so.1%{?elf_suffix}
+Recommends:     libdw.so.1(ELFUTILS_0.186)%{?elf_bits}
+Recommends:     libelf.so.1%{?elf_suffix}
+Recommends:     libelf.so.1(ELFUTILS_1.7)%{?elf_bits}
+
+# used by dissect, integritysetup, veritysetyp, growfs, repart, cryptenroll, home
+Recommends:     libcryptsetup.so.12%{?elf_suffix}
+Recommends:     libcryptsetup.so.12(CRYPTSETUP_2.4)%{?elf_bits}
+
 %description
-systemd is a system and service manager that runs as PID 1 and starts
-the rest of the system. It provides aggressive parallelization
-capabilities, uses socket and D-Bus activation for starting services,
-offers on-demand starting of daemons, keeps track of processes using
-Linux control groups, maintains mount and automount points, and
-implements an elaborate transactional dependency-based service control
-logic. systemd supports SysV and LSB init scripts and works as a
+systemd is a system and service manager that runs as PID 1 and starts the rest
+of the system. It provides aggressive parallelization capabilities, uses socket
+and D-Bus activation for starting services, offers on-demand starting of
+daemons, keeps track of processes using Linux control groups, maintains mount
+and automount points, and implements an elaborate transactional dependency-based
+service control logic. systemd supports SysV and LSB init scripts and works as a
 replacement for sysvinit. Other parts of this package are a logging daemon,
-utilities to control basic system configuration like the hostname,
-date, locale, maintain a list of logged-in users, system accounts,
-runtime directories and settings, and daemons to manage simple network
-configuration, network time synchronization, log forwarding, and name
-resolution.
+utilities to control basic system configuration like the hostname, date, locale,
+maintain a list of logged-in users, system accounts, runtime directories and
+settings, and a logging daemons.
 %if 0%{?stable}
 This package was built from the %{version}-stable branch of systemd.
 %endif
@@ -312,10 +265,6 @@ Obsoletes:      systemd-compat-libs < 230
 Obsoletes:      nss-myhostname < 0.4
 Provides:       nss-myhostname = 0.4
 Provides:       nss-myhostname%{_isa} = 0.4
-Requires(post): coreutils
-Requires(post): sed
-Requires(post): grep
-Requires(post): /usr/bin/getent
 
 %description libs
 Libraries for systemd and udev.
@@ -370,6 +319,23 @@ Provides:       udev = %{version}
 Provides:       udev%{_isa} = %{version}
 Obsoletes:      udev < 183
 
+# Recommends to replace normal Requires deps for stuff that is dlopen()ed
+# used by dissect, integritysetup, veritysetyp, growfs, repart, cryptenroll, home
+Recommends:     libcryptsetup.so.12%{?elf_suffix}
+Recommends:     libcryptsetup.so.12(CRYPTSETUP_2.4)%{?elf_bits}
+
+# used by systemd-coredump and systemd-analyze
+Recommends:     libdw.so.1%{?elf_suffix}
+Recommends:     libdw.so.1(ELFUTILS_0.186)%{?elf_bits}
+Recommends:     libelf.so.1%{?elf_suffix}
+Recommends:     libelf.so.1(ELFUTILS_1.7)%{?elf_bits}
+
+# used by home, cryptsetup, cryptenroll
+Recommends:     libfido2.so.1%{?elf_suffix}
+Recommends:     libtss2-esys.so.0%{?elf_suffix}
+Recommends:     libtss2-mu.so.0%{?elf_suffix}
+Recommends:     libtss2-rc.so.0%{?elf_suffix}
+
 # https://bugzilla.redhat.com/show_bug.cgi?id=1377733#c9
 Suggests:       systemd-bootchart
 # https://bugzilla.redhat.com/show_bug.cgi?id=1408878
@@ -380,9 +346,14 @@ Provides:       u2f-hidraw-policy = 1.0.2-40
 Obsoletes:      u2f-hidraw-policy < 1.0.2-40
 
 %description udev
-This package contains systemd-udev and the rules and hardware database
-needed to manage device nodes. This package is necessary on physical
-machines and in virtual machines, but not in containers.
+This package contains systemd-udev and the rules and hardware database needed to
+manage device nodes. This package is necessary on physical machines and in
+virtual machines, but not in containers.
+
+This package also provides systemd-timesyncd, a network time protocol daemon.
+
+It also contains tools to manage encrypted home areas and secrets bound to the
+machine, and to create or grow partitions and make file systems automatically.
 
 %package container
 # Name is the same as in Debian
@@ -393,33 +364,33 @@ Requires(preun):  systemd
 Requires(postun): systemd
 # obsolete parent package so that dnf will install new subpackage on upgrade (#1260394)
 Obsoletes:      %{name} < 229-5
+# Bias the system towards libcurl-minimal if nothing pulls in full libcurl (#1997040)
+Suggests:       libcurl-minimal
 License:        LGPLv2+
 
 %description container
 Systemd tools to spawn and manage containers and virtual machines.
 
-This package contains systemd-nspawn, machinectl, systemd-machined,
-and systemd-importd.
+This package contains systemd-nspawn, machinectl, systemd-machined, and
+systemd-importd.
 
 %package journal-remote
 # Name is the same as in Debian
 Summary:        Tools to send journal events over the network
 Requires:       %{name}%{?_isa} = %{version}-%{release}
 License:        LGPLv2+
-Requires(pre):    /usr/bin/getent
-Requires(post):   systemd
-Requires(preun):  systemd
-Requires(postun): systemd
 Provides:       %{name}-journal-gateway = %{version}-%{release}
 Provides:       %{name}-journal-gateway%{_isa} = %{version}-%{release}
 Obsoletes:      %{name}-journal-gateway < 227-7
+# Bias the system towards libcurl-minimal if nothing pulls in full libcurl (#1997040)
+Suggests:       libcurl-minimal
 
 %description journal-remote
-Programs to forward journal entries over the network, using encrypted HTTP,
-and to write journal files from serialized journal contents.
+Programs to forward journal entries over the network, using encrypted HTTP, and
+to write journal files from serialized journal contents.
 
-This package contains systemd-journal-gatewayd,
-systemd-journal-remote, and systemd-journal-upload.
+This package contains systemd-journal-gatewayd, systemd-journal-remote, and
+systemd-journal-upload.
 
 %package networkd
 Summary:        System daemon that manages network configurations
@@ -427,18 +398,21 @@ Requires:       %{name}%{?_isa} = %{version}-%{release}
 License:        LGPLv2+
 
 %description networkd
-systemd-networkd is a system service that manages networks. It detects
-and configures network devices as they appear, as well as creating virtual
-network devices.
+systemd-networkd is a system service that manages networks. It detects and
+configures network devices as they appear, as well as creating virtual network
+devices.
 
 %package resolved
 Summary:        Network Name Resolution manager
 Requires:       %{name}%{?_isa} = %{version}-%{release}
+Requires:       libidn2.so.0%{?elf_suffix}
+Requires:       libidn2.so.0(IDN2_0.0.0)%{?elf_bits}
+Requires(posttrans): grep
 
 %description resolved
-systemd-resolved is a system service that provides network name resolution
-to local applications. It implements a caching and validating DNS/DNSSEC
-stub resolver, as well as an LLMNR and MulticastDNS resolver and responder.
+systemd-resolved is a system service that provides network name resolution to
+local applications. It implements a caching and validating DNS/DNSSEC stub
+resolver, as well as an LLMNR and MulticastDNS resolver and responder.
 
 %package oomd-defaults
 Summary:        Configuration files for systemd-oomd
@@ -456,8 +430,8 @@ Requires:      %{name}%{?_isa} = %{version}-%{release}
 License:       LGPLv2+
 
 %description tests
-"Installed tests" that are usually run as part of the build system.
-They can be useful to test systemd internals.
+"Installed tests" that are usually run as part of the build system. They can be
+useful to test systemd internals.
 
 %if %{with selinux}
 %package selinux
@@ -479,15 +453,24 @@ runs properly under an environment with SELinux enabled.
 %endif
 
 %prep
-%autosetup -n %{?commit:%{name}%{?stable:-stable}-%{commit}}%{!?commit:%{name}%{?stable:-stable}-%{version_no_tilde}} -p1
+%autosetup -n %{name}-hs%{?facebook:fb}-%{version} -p1
 
 %if %{with selinux}
 mkdir selinux
 cp %SOURCE100 %SOURCE101 %SOURCE102 selinux
 %endif
 
+test -f src/login/systemd-user.in
+# Restore systemd-user pam config from before "removal of Fedora-specific bits".
+# We'll systemd process it and install in the right place.
+cp %{SOURCE12} src/login/systemd-user.in
+
+# Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=2057735
+cp /usr/include/linux/audit.h src/systemd/
+sed -r -i "s|generate_audit_type_list, cpp|& + ' -I/usr/include/linux'|" src/libsystemd/meson.build
+
 %build
-%define ntpvendor %(source /etc/os-release; echo ${ID})
+%global ntpvendor %(source /etc/os-release; echo ${ID})
 %{!?ntpvendor: echo 'NTP vendor zone is not set!'; exit 1}
 
 CONFIGURE_OPTS=(
@@ -506,6 +489,7 @@ CONFIGURE_OPTS=(
         -Dseccomp=true
         -Dima=true
         -Dselinux=true
+        -Dbpf-framework=true
         -Dapparmor=false
         -Dpolkit=true
         -Dxz=true
@@ -517,6 +501,8 @@ CONFIGURE_OPTS=(
         -Dacl=true
         -Dsmack=true
         -Dopenssl=true
+        -Dcryptolib=openssl
+        -Dp11kit=true
         -Dgcrypt=true
         -Daudit=true
         -Delfutils=true
@@ -526,17 +512,24 @@ CONFIGURE_OPTS=(
         -Dlibcryptsetup=false
 %endif
         -Delfutils=true
+        -Dpwquality=true
+        # C8S only ships v3.4.4 whereas v4 is required
+        -Dqrencode=false
         -Dgnutls=true
         -Dmicrohttpd=true
         -Dlibidn2=true
         -Dlibiptc=false
         -Dlibcurl=true
+        # Not available in EPEL 8 yet (https://bugzilla.redhat.com/show_bug.cgi?id=2059387).
+        -Dlibfido2=false
         -Defi=true
         -Dgnu-efi=%{?have_gnu_efi:true}%{?!have_gnu_efi:false}
         -Dtpm=true
         -Dtpm2=true
         -Dhwdb=true
         -Dsysusers=true
+        # Standalone binaries are only relevant on non-systemd systems
+        -Dstandalone-binaries=false
         -Ddefault-kill-user-processes=false
         -Dtests=unsafe
         -Dinstall-tests=true
@@ -565,18 +558,20 @@ CONFIGURE_OPTS=(
         # https://bugzilla.redhat.com/show_bug.cgi?id=1867830
         -Ddefault-mdns=no
         -Ddefault-llmnr=resolve
+        # https://bugzilla.redhat.com/show_bug.cgi?id=2028169
+        -Dstatus-unit-format-default=combined
         -Doomd=true
         -Dadm-gid=4
         -Daudio-gid=63
         -Dcdrom-gid=11
         -Ddialout-gid=18
         -Ddisk-gid=6
-        -Dinput-gid=104   # https://pagure.io/setup/pull-request/27
+        -Dinput-gid=104
         -Dkmem-gid=9
         -Dkvm-gid=36
         -Dlp-gid=7
-        -Drender-gid=105  # https://pagure.io/setup/pull-request/27
-        -Dsgx-gid=106     # https://pagure.io/setup/pull-request/27
+        -Drender-gid=105
+        -Dsgx-gid=106
         -Dtape-gid=33
         -Dtty-gid=5
         -Dusers-gid=100
@@ -589,19 +584,13 @@ CONFIGURE_OPTS=(
         # -Dsystemd-timesync-uid=, not set yet
         # Need to set this for CentOS build
         -Ddocdir=%{_pkgdocdir}
-        # CentOS is missing newer deps required to include these
-        # But also these aren't as relevant for the hyperscale use case
-        -Dp11kit=false
+        # These aren't as relevant for the hyperscale use case
         -Duserdb=false
         -Dhomed=false
-        -Dpwquality=false
-        -Dqrencode=false
-        -Dlibfido2=false
         # Old version of PAM might not support files in /usr/lib/pam.d/ so
         # stick with the old /etc/pam.d
         -Dpamconfdir=/etc/pam.d
-        # Standalone binaries are only relevant on non-systemd systems
-        -Dstandalone-binaries=false
+        -Dpcre2=true
 )
 
 %if 0%{?facebook}
@@ -666,6 +655,8 @@ mkdir -p %{buildroot}%{system_unit_dir}/dbus.target.wants
 mkdir -p %{buildroot}%{system_unit_dir}/syslog.target.wants
 mkdir -p %{buildroot}/run
 mkdir -p %{buildroot}%{_localstatedir}/log
+touch %{buildroot}%{_localstatedir}/log/lastlog
+chmod 0664 %{buildroot}%{_localstatedir}/log/lastlog
 touch %{buildroot}/run/utmp
 touch %{buildroot}%{_localstatedir}/log/{w,b}tmp
 
@@ -709,9 +700,6 @@ touch %{buildroot}%{_localstatedir}/lib/private/systemd/journal-upload/state
 # Install yum protection fragment
 install -Dm0644 %{SOURCE4} %{buildroot}/etc/dnf/protected.d/systemd.conf
 
-# Restore systemd-user pam config from before "removal of Fedora-specific bits"
-install -Dm0644 -t %{buildroot}/etc/pam.d/ %{SOURCE12}
-
 # Install additional docs
 # https://bugzilla.redhat.com/show_bug.cgi?id=1234951
 install -Dm0644 -t %{buildroot}%{_pkgdocdir}/ %{SOURCE9}
@@ -727,8 +715,6 @@ cat >%{buildroot}%{system_unit_dir}/systemd-hostnamed.service.d/disable-privated
 PrivateDevices=no
 EOF
 
-install -Dm0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE11}
-
 install -Dm0644 -t %{buildroot}%{_prefix}/lib/systemd/ %{SOURCE13}
 
 install -D -t %{buildroot}/usr/lib/systemd/ %{SOURCE3}
@@ -758,9 +744,10 @@ python3 %{SOURCE2} %buildroot <<EOF
 /usr/lib/systemd/purge-nobody-user
 %ghost %config(noreplace) /etc/vconsole.conf
 %ghost %config(noreplace) /etc/X11/xorg.conf.d/00-keyboard.conf
-%ghost %attr(0664,root,utmp) /run/utmp
-%ghost %attr(0664,root,utmp) /var/log/wtmp
-%ghost %attr(0660,root,utmp) /var/log/btmp
+%ghost %attr(0664,root,root) %verify(not group) /run/utmp
+%ghost %attr(0664,root,root) %verify(not group) /var/log/wtmp
+%ghost %attr(0660,root,root) %verify(not group) /var/log/btmp
+%ghost %attr(0664,root,root) %verify(not md5 size mtime group) /var/log/lastlog
 %ghost %config(noreplace) /etc/hostname
 %ghost %config(noreplace) /etc/localtime
 %ghost %config(noreplace) /etc/locale.conf
@@ -780,7 +767,7 @@ python3 %{SOURCE2} %buildroot <<EOF
 %ghost %dir /var/lib/systemd/linger
 %ghost /var/lib/systemd/random-seed
 %ghost %dir /var/lib/systemd/rfkill
-%ghost %dir %attr(2755, root, systemd-journal) %verify(not mode) /var/log/journal
+%ghost %dir %verify(not mode group) /var/log/journal
 %ghost %dir /var/log/journal/remote
 %ghost %attr(0700,root,root) %dir /var/log/private
 EOF
@@ -876,49 +863,7 @@ fi
 # a different package version.
 systemctl --no-reload preset systemd-oomd.service &>/dev/null || :
 
-%post libs
-%{?ldconfig}
-
-function mod_nss() {
-    if [ -f "$1" ] ; then
-        # Add nss-systemd to passwd and group
-        grep -E -q '^(passwd|group):.* systemd' "$1" ||
-        sed -i.bak -r -e '
-                s/^(passwd|group):(.*)/\1:\2 systemd/
-                ' "$1" &>/dev/null || :
-    fi
-}
-
-FILE="$(readlink /etc/nsswitch.conf || echo /etc/nsswitch.conf)"
-if [ "$FILE" = "/etc/authselect/nsswitch.conf" ] && authselect check &>/dev/null; then
-        mod_nss "/etc/authselect/user-nsswitch.conf"
-        authselect apply-changes &> /dev/null || :
-else
-        mod_nss "$FILE"
-        # also apply the same changes to user-nsswitch.conf to affect
-        # possible future authselect configuration
-        mod_nss "/etc/authselect/user-nsswitch.conf"
-fi
-
-# check if nobody or nfsnobody is defined
-export SYSTEMD_NSS_BYPASS_SYNTHETIC=1
-if getent passwd nfsnobody &>/dev/null; then
-   test -f /etc/systemd/dont-synthesize-nobody || {
-       echo 'Detected system with nfsnobody defined, creating /etc/systemd/dont-synthesize-nobody'
-       mkdir -p /etc/systemd || :
-       : >/etc/systemd/dont-synthesize-nobody || :
-   }
-elif getent passwd nobody 2>/dev/null | grep -v 'nobody:[x*]:65534:65534:.*:/:/sbin/nologin' &>/dev/null; then
-   test -f /etc/systemd/dont-synthesize-nobody || {
-       echo 'Detected system with incompatible nobody defined, creating /etc/systemd/dont-synthesize-nobody'
-       mkdir -p /etc/systemd || :
-       : >/etc/systemd/dont-synthesize-nobody || :
-   }
-fi
-
-%{?ldconfig:%postun libs -p %ldconfig}
-
-%global udev_services systemd-udev{d,-settle,-trigger}.service systemd-udevd-{control,kernel}.socket systemd-timesyncd.service
+%global udev_services systemd-udev{d,-settle,-trigger}.service systemd-udevd-{control,kernel}.socket systemd-timesyncd.service %{?have_gnu_efi:systemd-boot-update.service}
 
 %post udev
 # Move old stuff around in /var/lib
@@ -954,6 +899,7 @@ grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null &&
 # Others are either oneshot services, or sockets, and restarting them causes issues (#1378974)
 %systemd_postun_with_restart systemd-udevd.service systemd-timesyncd.service
 
+
 %global journal_remote_units_restart systemd-journal-gatewayd.service systemd-journal-remote.service systemd-journal-upload.service
 %global journal_remote_units_norestart systemd-journal-gatewayd.socket systemd-journal-remote.socket
 %post journal-remote
@@ -996,6 +942,14 @@ if [ $1 -eq 0 ] ; then
         systemctl disable --quiet \
                 systemd-resolved.service \
                 >/dev/null || :
+        if [ -L /etc/resolv.conf ] && \
+            realpath /etc/resolv.conf | grep ^/run/systemd/resolve/; then
+                rm -f /etc/resolv.conf # no longer useful
+                # if network manager is enabled, move to it instead
+                [ -f /run/NetworkManager/resolv.conf ] && \
+                systemctl -q is-enabled NetworkManager.service &>/dev/null && \
+                    ln -fsv ../run/NetworkManager/resolv.conf /etc/resolv.conf
+        fi
 fi
 
 %post resolved
@@ -1009,23 +963,32 @@ fi
 
 %systemd_post systemd-resolved.service
 
+%posttrans resolved
 # Create /etc/resolv.conf symlink.
 # We would also create it using tmpfiles, but let's do this here
 # too before NetworkManager gets a chance. (systemd-tmpfiles invocation above
 # does not do this, because it's marked with ! and we don't specify --boot.)
 # https://bugzilla.redhat.com/show_bug.cgi?id=1873856
 #
-# If systemd is not running, don't overwrite the symlink because that
-# will immediately break DNS resolution, since systemd-resolved is
-# also not running (https://bugzilla.redhat.com/show_bug.cgi?id=1891847).
+# *Create* the symlink if nothing is present yet.
+# (https://bugzilla.redhat.com/show_bug.cgi?id=2032085)
+#
+# *Override* the symlink if systemd is running. Don't do it if systemd
+# is not running, because that will immediately break DNS resolution,
+# since systemd-resolved is also not running
+# (https://bugzilla.redhat.com/show_bug.cgi?id=1891847).
 #
 # Also don't create the symlink to the stub when the stub is disabled (#1891847 again).
-if test -d /run/systemd/system/ &&
-   systemctl -q is-enabled systemd-resolved.service &>/dev/null &&
-   ! mountpoint /etc/resolv.conf &>/dev/null &&
-   ! systemd-analyze cat-config systemd/resolved.conf 2>/dev/null | \
-        grep -qE '^DNSStubListener\s*=\s*([nN][oO]?|[fF]|[fF][aA][lL][sS][eE]|0|[oO][fF][fF])$'; then
-  ln -fsv ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
+if systemctl -q is-enabled systemd-resolved.service &>/dev/null &&
+   ! systemd-analyze cat-config systemd/resolved.conf 2>/dev/null |
+        grep -iqE '^DNSStubListener\s*=\s*(no?|false|0|off)\s*$'; then
+
+  if ! test -e /etc/resolv.conf && ! test -L /etc/resolv.conf; then
+    ln -sv ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf || :
+  elif test -d /run/systemd/system/ &&
+     ! mountpoint /etc/resolv.conf &>/dev/null; then
+    ln -fsv ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf || :
+  fi
 fi
 
 %if %{with selinux}
@@ -1051,8 +1014,10 @@ fi
 
 %files -f %{name}.lang -f .file-list-rest
 %doc %{_pkgdocdir}
-%exclude %{_pkgdocdir}/LICENSE.*
+%exclude %{_pkgdocdir}/LICENSE*
+# Only the licenses texts for the licenses in License line are included.
 %license LICENSE.GPL2 LICENSE.LGPL2.1
+%license LICENSES/MIT.txt
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/basic.target.wants
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/bluetooth.target.wants
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/default.target.wants
@@ -1068,6 +1033,7 @@ fi
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/sysinit.target.wants
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/system-update.target.wants
 %ghost %dir %attr(0755,-,-) /etc/systemd/system/timers.target.wants
+%ghost %dir %attr(0700,-,-) /var/lib/portables
 %ghost %dir %attr(0755,-,-) /var/lib/rpm-state/systemd
 
 %files libs -f .file-list-libs
@@ -1084,6 +1050,7 @@ fi
 %files udev -f .file-list-udev
 
 %files container -f .file-list-container
+%ghost %dir %attr(0700,-,-) /var/lib/machines
 
 %files journal-remote -f .file-list-remote
 
@@ -1100,15 +1067,104 @@ fi
 %endif
 
 %changelog
+* Mon Feb 28 2022 Daan De Meyer <daan.j.demeyer@gmail.com> - 250.3-6.1
+- New release for v250
+- Sync latest changes from Fedora rawhide
+- Use source archives from https://pagure.io/centos-sig-hyperscale/systemd
+  instead of github. All Hyperscale patches have moved to pagure
+- Added llvm-toolset to BuildRequires (for llvm-strip) to make build succeed
+- Enable p11kit and pwquality options in the systemd build
+
+* Thu Feb 24 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-6
+- Avoid trying to create the symlink if there's a dangling symlink already in
+  place (#2058388)
+
 * Thu Feb 24 2022 Daan De Meyer <daan.j.demeyer@gmail.com> - 249-2.13
 - Move to dist-git layout used by Fedora (no more SOURCES/ and SPECS/)
 - Switch to .gitignore from commit 46a40810 from the Fedora RPM repo
 - Add back removed files from commit 46a40810 from the Fedora RPM repo
 
+* Wed Feb 23 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-5
+- Move part of %%post scriptlet for resolved to %%posttrans (#2018913)
+- Specify owner of utmp/wtmp/btmp/lastlog as root in the rpm listing
+
+* Wed Feb 16 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-4
+- Drop scriptlet for handling nobody user upgrades from Fedora <28
+- Specify owner of /var/log/journal as root in the rpm listing (#2018913)
+
+* Thu Feb 10 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-3
+- Add pam_namespace to systemd-user pam config (rhbz#2053098)
+- Drop 20-grubby.install plugin for kernel-install (rhbz#2033646)
+
 * Wed Feb 09 2022 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.12
 - Backport PR #20695: Sync if_arp.h with Linux 5.14
 - FB-only backport PR #22426: MemoryZSwapMax= to configure memory.zswap.max
 
+* Sat Jan 22 2022 Fedora Release Engineering <releng@fedoraproject.org>
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Jan 18 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-2
+- Take ghost ownership of /var/log/lastlog (#1798685)
+
+* Tue Jan 18 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.3-1
+- Third stable release after v250: fixes for sd-boot on fringe hardware (e.g. VirtualBox),
+  various man page updates, sd-journal file verification is now stricter,
+  systemd-networkd by default will not add routes for wireguard AllowedIPs=
+  systemd nss modules shouldn't try to read kernel command line
+- Don't do sd-boot updates when not installed (#2038289)
+- xdg-autostart-service will ignore ExecCondition= when the helper binary is missing
+- kernel-install does cleanup better (#2016630)
+
+* Fri Jan  7 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.2-1
+- Second stable release after v250: various bugfixes
+  (systemd-resolved, systemd-journald, userdbctl, homed).
+- The manager should now gracefully handle the case where BPF LSM
+  cannot be initialized (#2036145). The BPF filters are enabled again
+  on all architectures, so *other* filter should also work on the
+  affected architectures.
+- kernel-install now checks paths used by grub2 before sd-boot paths again
+  (#2036199)
+- fstab-generator now ignores root-on-nfs/cifs/iscsi and live (#2037233)
+- CVE-2021-3997, #2024639: systemd-tmpfiles would exhaust the stack and crash
+  during excessive recursion on a very deeply nested directory structure.
+
+* Tue Jan  4 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250.1-1
+- First stable version after v250: various bugfixes, in particular for
+  sd-boot, systemd-networkd, and various build issues.
+- Fixes #2036517, #2035608, #2036217.
+
+* Thu Dec 30 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250-3
+- Disable bpf filters on arm64 (#2036145)
+
+* Sat Dec 25 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250-2
+- Fix warning about systemd-boot-update.service not existing on
+  non-uefi architectures
+- Enable all bpf features (#2035608)
+
+* Thu Dec 23 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250-1
+- Version 250, only some very small changes since -rc3.
+- Switch unit status name format to 'combined' (#2028169)
+
+* Mon Dec 20 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250~rc3-1
+- Latest prerelease, see
+  https://raw.githubusercontent.com/systemd/systemd/v250-rc3/NEWS for
+  details.
+- Fixes rhbz#2006761, rhbz#2027627, rhbz#1926323, rhbz#1919538.
+
+* Sun Dec 12 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250~rc1-4
+- Move systemd-boot-update.service to -udev subpackage
+  and add it the the installation scriptlets (#2031400)
+- Move libcryptsetup-token-systemd plugins to -udev (#2031873)
+- Create /etc/resolv.conf symlink if nothing is present yet (#2032085)
+
+* Fri Dec 10 2021 Pavel Březina <pbrezina@redhat.com> - 250~rc1-3
+- Remove nsswitch.conf scriptlets (#2023743)
+
+* Thu Dec  9 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 250~rc1-1
+- Version 250-rc1,
+  see https://raw.githubusercontent.com/systemd/systemd/v250-rc1/NEWS for
+  details.
+
 * Tue Nov 30 2021 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.11
 - Backport PR #21241: fix bpf-foreign cgroup controller realization
 
@@ -1119,16 +1175,52 @@ fi
 * Wed Nov 24 2021 Davide Cavalca <dcavalca@centosproject.org> - 249.4-2.9
 - Disable legacy iptables support
 
+* Fri Nov 19 2021 Davide Cavalca <dcavalca@fedoraproject.org> - 249.7-3
+- Disable legacy iptables support
+
+* Mon Nov 15 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 249.7-2
+- Supress errors from update-helper when selinux is enabled (see #2023332)
+
+* Sun Nov 14 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 249.7-1
+- Latest bugfix release (better erofs detection, sd-event memory
+  corruption bugfix, logind, documentation)
+- Really fix helper to restart user units with older systemd (#2020415)
+
+* Sun Nov 14 2021 Petr Menšík <pemensik@redhat.com> - 249.7-1
+- Switch /etc/resolv.conf over to NM when systemd-resolved is uninstalled
+
 * Thu Nov 11 2021 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.8
 - Remove revert_d219a2b07cc5dc8ffd5010f08561fab2780d8616.patch and replace with
   proper fix (PR #21221)
 
+* Wed Nov 10 2021 Kir Kolyshkin <kolyshkin@gmail.com> - 249.7-1
+- Fix scope activation from a user instance (#2022041)
+
 * Wed Nov 10 2021 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.7
 - Add meson >= 0.57 for el8 builds. This version uses python 3.8.
 
+* Mon Nov  8 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 249.6-3
+- Fix helper to restart user units with older systemd (#2020415)
+
+* Thu Nov  4 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 249.6-2
+- Latest bugfix release (networkd, coredumpctl, varlink, udev,
+  systemctl, systemd itself, better detection of Hyper-V and
+  Virtualbox virtualization, documentation updates)
+- Fix helper to restart user units
+
+* Fri Oct 29 2021 Adam Williamson <awilliam@redhat.com> - 249.5-2
+- Backport PR #133 to fix boot
+
 * Wed Oct 20 2021 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.6
 - Revert d219a2b because it creates non-determinisitic Slice= assignments
 
+* Tue Oct 12 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 249.5-1
+- Latest bugfix release (various fixes in systemd-networkd,
+  -timesyncd, -journald, -udev, homed, -resolved, -repart, -oomd,
+  -coredump, systemd itself, seccomp filters, TPM2 handling,
+  -documentation, sd-event, sd-journal, journalctl, and nss-systemd).
+- Fixes #1976445.
+
 * Mon Oct 11 2021 Anita Zhang <the.anitazha@gmail.com> - 249.4-2.5
 - Remove duplicate Address= properties in network configs (part of PR #20892)
 - Serialize bpf device programs across reloads/reexecs (PR #20978)
diff --git a/sysusers.prov b/sysusers.prov
index a6eda5d..f12e929 100755
--- a/sysusers.prov
+++ b/sysusers.prov
@@ -1,5 +1,40 @@
 #!/bin/bash
 
+process_u() {
+    if [ ! -z "${2##*[!0-9]*}" ]; then
+        # Single shared static ID.
+        echo "user($1) = $2"
+        echo "group($1) = $2"
+    elif [[ $2 == *:* ]]; then
+        # UID:<group>.
+        uid=$(echo $2 | cut -d':' -f1 -)
+        group=$(echo $2 | cut -d':' -f2 -)
+        if [ ! -z "${group##*[!0-9]*}" ]; then
+            # UID:GID.
+            echo "user($1) = ${uid}"
+            echo "group($1) = ${group}"
+        else
+            # UID:<groupname>.
+            echo "user($1) = ${uid}"
+            echo "group(${group})"
+        fi
+    else
+        # Dynamic (or something else uninteresting).
+        echo "user($1)"
+        echo "group($1)"
+    fi
+}
+
+process_g() {
+    if [ ! -z "${2##*[!0-9]*}" ]; then
+        # Static GID.
+        echo "group($1) = $2"
+    else
+        # Dynamic (or something else uninteresting).
+        echo "group($1)"
+    fi
+}
+
 parse() {
     while read line; do
         [ "${line:0:1}" = '#' -o "${line:0:1}" = ';' ] && continue
@@ -8,12 +43,10 @@ parse() {
         set -- $line
         case "$1" in
             ('u')
-                echo "user($2)"
-                echo "group($2)"
-                # TODO: user:group support
+                process_u "$2" "$3"
                 ;;
             ('g')
-                echo "group($2)"
+                process_g "$2" "$3"
                 ;;
             ('m')
                 echo "user($2)"
diff --git a/triggers.systemd b/triggers.systemd
index 6c57d71..5929035 100644
--- a/triggers.systemd
+++ b/triggers.systemd
@@ -14,9 +14,13 @@
 # upgraded. We care about the case where a package is initially
 # installed, because other cases are covered by the *un scriptlets,
 # so sometimes we will reload needlessly.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl daemon-reload || :
-  %{_bindir}/systemctl reload-or-restart --marked || :
+/usr/lib/systemd/systemd-update-helper system-reload-restart || :
+
+%transfiletriggerin -P 900899 -- /usr/lib/systemd/user /etc/systemd/user
+if selinuxenabled &>/dev/null; then
+  /usr/lib/systemd/systemd-update-helper user-reload-restart 2>/dev/null || :
+else
+  /usr/lib/systemd/systemd-update-helper user-reload-restart || :
 fi
 
 %transfiletriggerpostun -P 1000100 -- /usr/lib/systemd/system /etc/systemd/system
@@ -25,14 +29,26 @@ fi
 # On upgrade, we need to run daemon-reload after any new unit files
 # have been installed, but before %postun scripts in packages get
 # executed.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl daemon-reload || :
+/usr/lib/systemd/systemd-update-helper system-reload || :
+
+%transfiletriggerpostun -P 1000099 -- /usr/lib/systemd/user /etc/systemd/user
+# Execute daemon-reload in user managers.
+if selinuxenabled &>/dev/null; then
+  /usr/lib/systemd/systemd-update-helper user-reload 2>/dev/null || :
+else
+  /usr/lib/systemd/systemd-update-helper user-reload || :
 fi
 
 %transfiletriggerpostun -P 10000 -- /usr/lib/systemd/system /etc/systemd/system
-# We restart remaining services that should be restarted here.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl reload-or-restart --marked || :
+# We restart remaining system services that should be restarted here.
+/usr/lib/systemd/systemd-update-helper system-restart || :
+
+%transfiletriggerpostun -P  9999 -- /usr/lib/systemd/user /etc/systemd/user
+# We restart remaining user services that should be restarted here.
+if selinuxenabled &>/dev/null; then
+  /usr/lib/systemd/systemd-update-helper user-restart 2>/dev/null || :
+else
+  /usr/lib/systemd/systemd-update-helper user-restart || :
 fi
 
 %transfiletriggerin -P 1000700 -- /usr/lib/sysusers.d
@@ -40,21 +56,21 @@ fi
 # specified users automatically. The priority is set such that it
 # will run before the tmpfiles file trigger.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-sysusers || :
+  systemd-sysusers || :
 fi
 
 %transfiletriggerin -P 1000700 udev -- /usr/lib/udev/hwdb.d
 # This script will automatically invoke hwdb update if files have been
 # installed or updated in /usr/lib/udev/hwdb.d.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-hwdb update || :
+  systemd-hwdb update || :
 fi
 
 %transfiletriggerin -P 1000700 -- /usr/lib/systemd/catalog
 # This script will automatically invoke journal catalog update if files
 # have been installed or updated in /usr/lib/systemd/catalog.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/journalctl --update-catalog || :
+  journalctl --update-catalog || :
 fi
 
 %transfiletriggerin -P 1000700 -- /usr/lib/binfmt.d
@@ -71,14 +87,14 @@ fi
 # tmpfiles automatically. The priority is set such that it will run
 # after the sysusers file trigger, but before any other triggers.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-tmpfiles --create || :
+  systemd-tmpfiles --create || :
 fi
 
 %transfiletriggerin -P 1000600 udev -- /usr/lib/udev/rules.d
 # This script will automatically update udev with new rules if files
 # have been installed or updated in /usr/lib/udev/rules.d.
 if test -e /run/udev/control; then
-  %{_bindir}/udevadm control --reload || :
+  udevadm control --reload || :
 fi
 
 %transfiletriggerin -P 1000500 -- /usr/lib/sysctl.d