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 ba87a61d05.
Fixes #36997.
This commit is contained in:
Yu Watanabe
2025-06-11 18:05:46 +09:00
parent a954c1945b
commit 78f8d5ed71
3 changed files with 53 additions and 10 deletions

View File

@@ -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);

View File

@@ -0,0 +1,8 @@
# SPDX-License-Identifier: MIT-0
[Match]
Kind=dummy
OriginalName=test1
[Link]
NamePolicy=keep
Property=ID_NET_MANAGED_BY=hoge

View File

@@ -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,