]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: ensure that unmanaged interfaces aren't touched
authorMatteo Croce <teknoraver@meta.com>
Mon, 19 May 2025 21:35:23 +0000 (23:35 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 May 2025 18:04:40 +0000 (03:04 +0900)
Extend the test_keep_configuration_on_restart in order to check
that the unmanaged interface isn't altered in any way.

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

diff --git a/test/test-network/conf/85-unmanaged.link b/test/test-network/conf/85-unmanaged.link
new file mode 100644 (file)
index 0000000..4444f1d
--- /dev/null
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: MIT-0
+#
+# This config file is installed as part of systemd.
+# It may be freely copied and edited (following the MIT No Attribution license).
+#
+# To make local modifications, use "networkctl edit". See networkctl(1) for details.
+# This file should not be edited in place, because it'll be overwritten on upgrades.
+
+# This .link file matches a dummy Ethernet link created to check if
+# networkd touches an unmanaged interface by mistake
+
+[Match]
+Kind=dummy
+OriginalName=unmanaged0
+
+[Link]
+NamePolicy=keep
+Property=ID_NET_MANAGED_BY=io.systemd.Network
index fbf5354eb58994fc6523a148d170537863ec8e8e..cd65c9adaf655ac1921ddba1b59e0859471e714b 100755 (executable)
@@ -5028,40 +5028,60 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
         self.assertIn('default via fe80::f0ca:cc1a proto static metric 1 pref medium', output)
 
     def test_keep_configuration_on_restart(self):
+        copy_network_unit('12-dummy.netdev', '85-static-ipv6.network', '85-unmanaged.link')
+
         # Add an unmanaged interface with an up address
         call('ip link add unmanaged0 type dummy')
         call('ip link set unmanaged0 up')
+        call('ip -4 addr add 10.20.30.40/32 dev unmanaged0')
         call('ip -6 addr add 2001:db8:9999:f101::15/64 dev unmanaged0')
 
-        copy_network_unit('12-dummy.netdev', '85-static-ipv6.network')
-        start_networkd()
-        self.check_keep_configuration_on_restart()
-
         # Start `ip monitor` with output to a temporary file
-        with tempfile.TemporaryFile(mode='r+', prefix='ip_monitor') as logfile:
-            process = subprocess.Popen(['ip', 'monitor', 'dev', 'dummy98'], stdout=logfile, text=True)
-            restart_networkd()
+        with tempfile.TemporaryFile(mode='r+', prefix='ip_monitor_u') as logfile_unmanaged:
+            process_u = subprocess.Popen(['ip', 'monitor', 'dev', 'unmanaged0'], stdout=logfile_unmanaged, text=True)
+
+            start_networkd()
             self.check_keep_configuration_on_restart()
 
-            process.send_signal(signal.SIGTERM)
-            process.wait()
+            # Start `ip monitor` with output to a temporary file
+            with tempfile.TemporaryFile(mode='r+', prefix='ip_monitor') as logfile:
+                process = subprocess.Popen(['ip', 'monitor', 'dev', 'dummy98'], stdout=logfile, text=True)
+
+                restart_networkd()
+                self.check_keep_configuration_on_restart()
 
-            print('### ip monitor dev dummy98 BEGIN')
+                process.send_signal(signal.SIGTERM)
+                process.wait()
+
+                print('### ip monitor dev dummy98 BEGIN')
+
+                # Read the `ip monitor` output looking for network changes
+                logfile.seek(0)
+                for line in logfile:
+                    print(line, end="")
+                    # Check if a link went down
+                    self.assertNotRegex(line, 'dummy98: .* state DOWN')
+                    # Check if an address was removed
+                    self.assertNotRegex(line, '^Deleted .* 2001:db8:')
+                    self.assertNotRegex(line, '^Deleted 2001:db8:.*/64')
+                    # Check if the default route was removed
+                    self.assertNotRegex(line, '^Deleted default via fe80::f0ca:cc1a')
+
+            print('### ip monitor dev dummy98 END')
+
+            process_u.send_signal(signal.SIGTERM)
+            process_u.wait()
+
+            print('### ip monitor dev unmanaged0 BEGIN')
 
             # Read the `ip monitor` output looking for network changes
-            logfile.seek(0)
-            for line in logfile:
+            logfile_unmanaged.seek(0)
+            for line in logfile_unmanaged:
                 print(line, end="")
-                # Check if a link went down
-                self.assertNotRegex(line, 'unmanaged0: .* state DOWN')
-                self.assertNotRegex(line, 'dummy98: .* state DOWN')
-                # Check if an address was removed
-                self.assertNotRegex(line, '^Deleted .* 2001:db8:')
-                self.assertNotRegex(line, '^Deleted 2001:db8:.*/64')
-                # Check if the default route was removed
-                self.assertNotRegex(line, '^Deleted default via fe80::f0ca:cc1a')
+                # Check if something happened
+                self.assertNotEmpty(line)
 
-            print('### ip monitor dev dummy98 END')
+        print('### ip monitor dev unmanaged0 END')
 
     def test_keep_untracked_addresses(self):
         # Add an unmanaged interface with an up address