]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: also check ID_NET_MANAGED_BY property on reconfigure
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Jun 2025 09:05:46 +0000 (18:05 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 25 Jun 2025 12:36:10 +0000 (13:36 +0100)
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.

(cherry picked from commit 78f8d5ed71ecc16ad36d1c215d2d57433d127679)

src/network/networkd-link.c
test/test-network/conf/11-dummy-unmanaged.link [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py

index 84330cb33a416982ff183878b2a119f7d973b362..78f318b975709244eccbc38c2bc6dc3821d3a7cb 100644 (file)
@@ -1365,6 +1365,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;
@@ -1380,6 +1406,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);
@@ -1617,6 +1647,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)
@@ -1684,7 +1718,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);
@@ -1719,15 +1752,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 (file)
index 0000000..99c07a7
--- /dev/null
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: MIT-0
+[Match]
+Kind=dummy
+OriginalName=test1
+
+[Link]
+NamePolicy=keep
+Property=ID_NET_MANAGED_BY=hoge
index 420c4b98320d30daf9a4b3aceaa8db34b2d58f71..1deff225bc82a651f058ade3898b885ceb835607 100755 (executable)
@@ -3230,6 +3230,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,