Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion SPECS-SIGNED/systemd-boot-signed/systemd-boot-signed.spec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Version: 255
# determine the build information from local checkout
Version: %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/')
%endif
Release: 34%{?dist}
Release: 35%{?dist}
License: LGPL-2.1-or-later AND MIT AND GPL-2.0-or-later
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand Down Expand Up @@ -98,6 +98,9 @@ popd
/boot/efi/EFI/BOOT/%{grubefiname}

%changelog
* Thu Oct 22 2026 Alex Cortelyou <alcortel@microsoft.com> - 255-35
- Bump release to match systemd spec.

* Mon Aug 17 2026 Aditya Singh <v-aditysing@microsoft.com> - 255-34
- Bump release to match systemd spec.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
From c2eb7753dd47ec04ae0d66400e70bc87fbf1adcc Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 15 Jan 2024 15:40:54 +0900
Subject: [PATCH] network/link: automatically reconfigure interface on failure

Closes #29246.
---
src/network/networkd-link.c | 20 +++++++++++++++++++-
src/network/networkd-link.h | 2 ++
2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 4e5ad3c035e2..9e69624fd2b5 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -381,6 +381,8 @@ int link_stop_engines(Link *link, bool may_keep_dhcp) {
}

void link_enter_failed(Link *link) {
+ int r;
+
assert(link);

if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
@@ -390,7 +392,22 @@ void link_enter_failed(Link *link) {

link_set_state(link, LINK_STATE_FAILED);

- (void) link_stop_engines(link, false);
+ if (!ratelimit_below(&link->automatic_reconfigure_ratelimit)) {
+ log_link_warning(link, "The interface entered the failed state frequently, refusing to reconfigure it automatically.");
+ goto stop;
+ }
+
+ log_link_info(link, "Trying to reconfigure the interface.");
+ r = link_reconfigure(link, /* force = */ true);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to reconfigure interface: %m");
+ goto stop;
+ }
+
+ return;
+
+stop:
+ (void) link_stop_engines(link, /* may_keep_dhcp = */ false);
}

void link_check_ready(Link *link) {
@@ -2552,6 +2569,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
.n_ref = 1,
.state = LINK_STATE_PENDING,
.online_state = _LINK_ONLINE_STATE_INVALID,
+ .automatic_reconfigure_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_SEC, .burst = 5 },
.ifindex = ifindex,
.iftype = iftype,
.ifname = TAKE_PTR(ifname),
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index cad9fa841068..05b028dff31d 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -25,6 +25,7 @@
#include "networkd-ipv6ll.h"
#include "networkd-util.h"
#include "ordered-set.h"
+#include "ratelimit.h"
#include "resolve-util.h"
#include "set.h"

@@ -106,6 +107,7 @@ typedef struct Link {
LinkAddressState ipv4_address_state;
LinkAddressState ipv6_address_state;
LinkOnlineState online_state;
+ RateLimit automatic_reconfigure_ratelimit;

unsigned static_address_messages;
unsigned static_address_label_messages;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
From 685fd0d729718aab45a19567a889c8baa2e6cc65 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 21 Aug 2024 07:01:47 +0900
Subject: [PATCH] network: enter initialized state when the interface will be
reconfigured

When the interface is in the failed state, link_getlink_handler_internal()
will do nothing and return zero, thus the interface will not be
reconfigured, especially when the reconfiguration is triggered in
link_enter_failed().

Follow-up for c2eb7753dd47ec04ae0d66400e70bc87fbf1adcc.
---
[Backport to v255: omit only the link_reconfigure_on_bus_method_reload()
hunk; that helper does not exist in v255. Retain both other hunks unchanged.]

src/network/networkd-link-bus.c | 1 -
src/network/networkd-link.c | 3 +++
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
index 84ed42987c51..ef2e81125577 100644
--- a/src/network/networkd-link-bus.c
+++ b/src/network/networkd-link-bus.c
@@ -669,7 +669,6 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
if (r < 0)
return r;
if (r > 0) {
- link_set_state(l, LINK_STATE_INITIALIZED);
r = link_save_and_clean_full(l, /* also_save_manager = */ true);
if (r < 0)
return r;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 3940aa79b37e..2f7aaec2e509 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1454,6 +1454,9 @@ int link_reconfigure(Link *link, bool force) {
if (r < 0)
return r;

+ if (force || link->state == LINK_STATE_FAILED)
+ link_set_state(link, LINK_STATE_INITIALIZED);
+
return 1; /* 1 means the interface will be reconfigured. */
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From e5b19cbed2032db214eec9a6191866f6f96355ef Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 21 Aug 2024 11:24:14 +0900
Subject: [PATCH] sd-dhcp-client: do not call callback with
SD_DHCP_CLIENT_EVENT_STOP if already stopped

When an interface enters the failed state, even if the DHCP client is
stopped, the acquired DHCP lease is not unreferenced, as the callback
dhcp4_handler() do nothing in that case. When the failed interface is
being reconfigured after that, the DHCP client is stopped again
(though it is already stopped), and SD_DHCP_CLIENT_EVENT_STOP event is
triggered and sd_dhcp_client_send_release() is called, and the
assertion in the function is triggered.

E.g.
===
systemd-networkd[98588]: wlp59s0: DHCPv4 address 192.168.86.250/24, gateway 192.168.86.1 acquired from 192.168.86.1
systemd-networkd[98588]: wlp59s0: Could not set DHCPv4 route: Nexthop has invalid gateway. Network is unreachable
systemd-networkd[98588]: wlp59s0: Failed
systemd-networkd[98588]: wlp59s0: State changed: configuring -> failed
systemd-networkd[98588]: wlp59s0: The interface entered the failed state frequently, refusing to reconfigure it automatically.
systemd-networkd[98588]: wlp59s0: DHCPv4 client: STOPPED
systemd-networkd[98588]: wlp59s0: DHCPv4 client: State changed: bound -> stopped
systemd-networkd[98588]: Got message type=method_call sender=:1.449 destination=org.freedesktop.network1 path=/org/freedesktop/network1 interface=org.freedesktop.network1.Manager member=ReconfigureLink ...
systemd-networkd[98588]: wlp59s0: State changed: failed -> initialized
systemd-networkd[98588]: wlp59s0: found matching network '/etc/systemd/network/50-wifi.network'.
systemd-networkd[98588]: wlp59s0: Configuring with /etc/systemd/network/50-wifi.network.
systemd-networkd[98588]: wlp59s0: DHCPv4 client: STOPPED
systemd-networkd[98588]: Assertion 'sd_dhcp_client_is_running(client)' failed at src/libsystemd-network/sd-dhcp-client.c:2197, function sd_dhcp_client_send_release(). Aborting.
===
---
src/libsystemd-network/sd-dhcp-client.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 1eb8509f0f6a..8b8d0611a272 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -683,15 +683,21 @@ static int client_initialize(sd_dhcp_client *client) {

static void client_stop(sd_dhcp_client *client, int error) {
assert(client);
+ DHCP_CLIENT_DONT_DESTROY(client);

- if (error < 0)
- log_dhcp_client_errno(client, error, "STOPPED: %m");
- else if (error == SD_DHCP_CLIENT_EVENT_STOP)
- log_dhcp_client(client, "STOPPED");
- else
- log_dhcp_client(client, "STOPPED: Unknown event");
-
- client_notify(client, error);
+ if (sd_dhcp_client_is_running(client)) {
+ if (error < 0)
+ log_dhcp_client_errno(client, error, "STOPPED: %m");
+ else if (error == SD_DHCP_CLIENT_EVENT_STOP)
+ log_dhcp_client(client, "STOPPED");
+ else
+ log_dhcp_client(client, "STOPPED: Unknown event");
+
+ client_notify(client, error);
+ } else if (error < 0) {
+ log_dhcp_client_errno(client, error, "FAILED: %m");
+ client_notify(client, error);
+ }

client_initialize(client);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
From f8cdd37d0aed8423d6744dd6637955760346939a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 21 Aug 2024 10:23:06 +0900
Subject: [PATCH] sd-dhcp-client: refuse to send RELEASE or friends gracefully
when the daemon is stopped or so

We can easily hit the assertions without checking the internal states of
the DHCP client before calling these functions. That's annoying.
Let's do more gracefully.
---
[Backport to v255: the retry counter is named attempt rather than
discover_attempt. Only unchanged context is adjusted.]

src/libsystemd-network/sd-dhcp-client.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 8b8d0611a272..94ad5bbea956 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -2138,14 +2138,8 @@ static int client_receive_message_raw(
}

int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
- assert_return(client, -EINVAL);
- assert_return(sd_dhcp_client_is_running(client), -ESTALE);
- assert_return(client->fd >= 0, -EINVAL);
-
- if (client->state != DHCP_STATE_BOUND)
- return 0;
-
- assert(client->lease);
+ if (!sd_dhcp_client_is_running(client) || client->state != DHCP_STATE_BOUND)
+ return 0; /* do nothing */

client->start_delay = 0;
client->attempt = 1;
@@ -2199,14 +2193,13 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
}

int sd_dhcp_client_send_release(sd_dhcp_client *client) {
- assert_return(client, -EINVAL);
- assert_return(sd_dhcp_client_is_running(client), -ESTALE);
- assert_return(client->lease, -EUNATCH);
-
_cleanup_free_ DHCPPacket *release = NULL;
size_t optoffset, optlen;
int r;

+ if (!sd_dhcp_client_is_running(client) || !client->lease)
+ return 0; /* do nothing */
+
r = client_message_init(client, &release, DHCP_RELEASE, &optlen, &optoffset);
if (r < 0)
return r;
@@ -2234,14 +2227,13 @@ int sd_dhcp_client_send_release(sd_dhcp_client *client) {
}

int sd_dhcp_client_send_decline(sd_dhcp_client *client) {
- assert_return(client, -EINVAL);
- assert_return(sd_dhcp_client_is_running(client), -ESTALE);
- assert_return(client->lease, -EUNATCH);
-
_cleanup_free_ DHCPPacket *release = NULL;
size_t optoffset, optlen;
int r;

+ if (!sd_dhcp_client_is_running(client) || !client->lease)
+ return 0; /* do nothing */
+
r = client_message_init(client, &release, DHCP_DECLINE, &optlen, &optoffset);
if (r < 0)
return r;
21 changes: 20 additions & 1 deletion SPECS/systemd/systemd.spec
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Version: 255
# determine the build information from local checkout
Version: %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/')
%endif
Release: 34%{?dist}
Release: 35%{?dist}

# FIXME - hardcode to 'stable' for now as that's what we have in our blobstore
%global stable 1
Expand Down Expand Up @@ -161,6 +161,16 @@ Patch0913: network-also-check-ID_NET_MANAGED_BY-property-on-rec.patch
Patch0914: Prevent-corruption-from-stale-alias-state-on-daemon-reload.patch
Patch0915: CVE-2026-15059.patch
Patch0916: CVE-2026-16742.patch
# PR 30936 and its recovery follow-ups, one upstream commit per patch.
Patch0917: network-link-automatically-reconfigure-on-failure.patch
Patch0918: test-network-flip-interface-state-frequently.patch
Patch0919: network-link-initialize-before-reconfiguration.patch
Patch0920: sd-dhcp-client-avoid-duplicate-stop-notification.patch
Patch0921: sd-dhcp-client-handle-stopped-renew-release-decline.patch
# Downstream regression coverage is separate from the upstream patches.
Patch0922: test-networkd-failed-link-and-dhcp-client-recovery.patch
# Test-only prerequisite for the build environment's OpenSSL output.
Patch0923: ukify-test-handle-openssl-issuer-whitespace.patch

%ifarch %{ix86} x86_64 aarch64
%global want_bootloader 1
Expand Down Expand Up @@ -1259,6 +1269,15 @@ rm -f %{name}.lang
# %autochangelog. So we need to continue manually maintaining the
# changelog here.
%changelog
* Thu Oct 22 2026 Alex Cortelyou <alcortel@microsoft.com> - 255-35
- Backport upstream PR 30936 to automatically reconfigure failed network interfaces
with rate-limited retries, including the interface-flapping regression test.
- Include upstream failed-state transition, duplicate DHCP STOP notification,
and graceful DHCP renew/release/decline follow-ups from PR 34054.
- Preserve individual upstream commits and keep downstream regression tests
separate; omit the unrelated CAN readiness cleanup.
- Backport the upstream ukify test fix for OpenSSL certificate issuer whitespace.

* Thu Aug 13 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 255-34
- Patch for CVE-2026-16742, CVE-2026-15059

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
From 6d1cea7bc6b26695fa6121e2d4270a30af9af3b3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 15 Jan 2024 15:17:57 +0900
Subject: [PATCH] test-network: try to flip interface state frequently

---
[Backport to v255: adjust test context for the older preceding test and
networkctl invocation. All upstream additions and deletions are unchanged.]

test/test-network/systemd-networkd-tests.py | 25 ++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index 161032105312..44970193677f 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -12,6 +12,7 @@
import json
import os
import pathlib
+import random
import re
import shutil
import signal
@@ -4881,6 +4882,4 @@ def test_ipv6_prefix_delegation(self):
- def test_ipv6_token_static(self):
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network')
- start_networkd()
+ def check_ipv6_token_static(self):
self.wait_online(['veth99:routable', 'veth-peer:degraded'])

output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
@@ -5121,6 +5120,26 @@ def test_ipv6_token_static(self):
self.assertRegex(output, '2002:da8:2:0:1a:2b:3c:4d')
self.assertRegex(output, '2002:da8:2:0:fa:de:ca:fe')

+ def test_ipv6_token_static(self):
+ copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network')
+ start_networkd()
+
+ self.check_ipv6_token_static()
+
+ for _ in range(20):
+ check_output('ip link set veth99 down')
+ check_output('ip link set veth99 up')
+
+ self.check_ipv6_token_static()
+
+ for _ in range(20):
+ check_output('ip link set veth99 down')
+ time.sleep(random.uniform(0, 0.1))
+ check_output('ip link set veth99 up')
+ time.sleep(random.uniform(0, 0.1))
+
+ self.check_ipv6_token_static()
+
def test_ipv6_token_prefixstable(self):
copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-prefixstable.network')
start_networkd()
Loading
Loading