diff --git a/SOURCES/20676_cherrypicked.patch b/SOURCES/20676_cherrypicked.patch
new file mode 100644
index 0000000..e97a589
--- /dev/null
+++ b/SOURCES/20676_cherrypicked.patch
@@ -0,0 +1,336 @@
+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/SOURCES/20978.patch b/SOURCES/20978.patch
new file mode 100644
index 0000000..8330e00
--- /dev/null
+++ b/SOURCES/20978.patch
@@ -0,0 +1,126 @@
+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/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch b/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch
new file mode 100644
index 0000000..6b148ad
--- /dev/null
+++ b/SOURCES/50783f91d44b1978c0e4ba62283131fac75d3745_cherrypicked.patch
@@ -0,0 +1,116 @@
+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/SPECS/systemd.spec b/SPECS/systemd.spec
index d514bc8..25924ab 100644
--- a/SPECS/systemd.spec
+++ b/SPECS/systemd.spec
@@ -40,7 +40,7 @@ Name:           systemd
 Url:            https://www.freedesktop.org/wiki/Software/systemd
 %if %{without inplace}
 Version:        249.4
-Release:        2.4%{?dist}
+Release:        2.5%{?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/')
@@ -126,9 +126,17 @@ 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
-Patch0017:      https://github.com/systemd/systemd/pull/20875.patch
+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
 
 # Downstream-only patches (0500–9999)
 
@@ -1073,6 +1081,11 @@ fi
 %endif
 
 %changelog
+* 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)
+- Don't rewrite sysctls that are already set (PR #20676)
+
 * Wed Oct 06 2021 Davide Cavalca <dcavalca@centosproject.org> - 249.4-2.4
 - Drop qrencode-devel from BuildRequires as it's not actually used