From: Yu Watanabe Date: Wed, 11 Jun 2025 09:05:46 +0000 (+0900) Subject: network: also check ID_NET_MANAGED_BY property on reconfigure X-Git-Tag: v258-rc1~333 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=78f8d5ed71ecc16ad36d1c215d2d57433d127679;p=thirdparty%2Fsystemd.git network: also check ID_NET_MANAGED_BY property on reconfigure Previously, the property was checked only when an uevent is received, so even if an interface has ID_NET_MANAGED_BY property, the interface will be configured by networkd when reconfiguration is triggered e.g. when interface state is changed. Follow-up for ba87a61d05d637be9f0b21707f7fe3b0a74c5a05. Fixes #36997. --- diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 65fd8b43e3b..4f7e1a15525 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1369,6 +1369,32 @@ static void link_enter_unmanaged(Link *link) { link_set_state(link, LINK_STATE_UNMANAGED); } +static int link_managed_by_us(Link *link) { + int r; + + assert(link); + + if (!link->dev) + return true; + + const char *s; + r = sd_device_get_property_value(link->dev, "ID_NET_MANAGED_BY", &s); + if (r == -ENOENT) + return true; + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get ID_NET_MANAGED_BY udev property: %m"); + + if (streq(s, "io.systemd.Network")) + return true; + + if (link->state == LINK_STATE_UNMANAGED) + return false; /* Already in unmanaged state */ + + log_link_debug(link, "Interface is requested to be managed by '%s', unmanaging the interface.", s); + link_set_state(link, LINK_STATE_UNMANAGED); + return false; +} + int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags) { Network *network = NULL; int r; @@ -1384,6 +1410,10 @@ int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags) { if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER)) return 0; + r = link_managed_by_us(link); + if (r <= 0) + return r; + r = link_get_network(link, &network); if (r == -ENOENT) { link_enter_unmanaged(link); @@ -1621,6 +1651,10 @@ static int link_initialized(Link *link, sd_device *device) { * or sysattrs) may be outdated. */ device_unref_and_replace(link->dev, device); + r = link_managed_by_us(link); + if (r <= 0) + return r; + if (link->dhcp_client) { r = sd_dhcp_client_attach_device(link->dhcp_client, link->dev); if (r < 0) @@ -1688,7 +1722,6 @@ int link_check_initialized(Link *link) { int manager_udev_process_link(Manager *m, sd_device *device, sd_device_action_t action) { int r, ifindex; - const char *s; Link *link; assert(m); @@ -1723,15 +1756,6 @@ int manager_udev_process_link(Manager *m, sd_device *device, sd_device_action_t return 0; } - r = sd_device_get_property_value(device, "ID_NET_MANAGED_BY", &s); - if (r < 0 && r != -ENOENT) - log_device_debug_errno(device, r, "Failed to get ID_NET_MANAGED_BY udev property, ignoring: %m"); - if (r >= 0 && !streq(s, "io.systemd.Network")) { - log_device_debug(device, "Interface is requested to be managed by '%s', not managing the interface.", s); - link_set_state(link, LINK_STATE_UNMANAGED); - return 0; - } - r = link_initialized(link, device); if (r < 0) link_enter_failed(link); diff --git a/test/test-network/conf/11-dummy-unmanaged.link b/test/test-network/conf/11-dummy-unmanaged.link new file mode 100644 index 00000000000..99c07a72ce3 --- /dev/null +++ b/test/test-network/conf/11-dummy-unmanaged.link @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: MIT-0 +[Match] +Kind=dummy +OriginalName=test1 + +[Link] +NamePolicy=keep +Property=ID_NET_MANAGED_BY=hoge diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 8ecae739664..91e51ba1426 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -3397,6 +3397,17 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): def tearDown(self): tear_down_common() + def test_ID_NET_MANAGED_BY(self): + copy_network_unit('11-dummy.netdev', '11-dummy-unmanaged.link', '11-dummy.network') + start_networkd() + self.wait_online('test1:off', setup_state='unmanaged') + + check_output('ip link set dev test1 up') + self.wait_online('test1:degraded', setup_state='unmanaged') + + check_output('ip link set dev test1 down') + self.wait_online('test1:off', setup_state='unmanaged') + def verify_address_static( self, label1: str,