networkd: ensure that unmanaged interfaces aren't touched

Extend the test_keep_configuration_on_restart in order to check
that the unmanaged interface isn't altered in any way.
This commit is contained in:
Matteo Croce
2025-05-19 23:35:23 +02:00
committed by Yu Watanabe
parent c450027d14
commit bcb9e72b6b
2 changed files with 60 additions and 22 deletions

View File

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

View File

@@ -5028,41 +5028,61 @@ 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)
print('### ip monitor dev dummy98 BEGIN')
restart_networkd()
self.check_keep_configuration_on_restart()
# 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, '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')
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_unmanaged.seek(0)
for line in logfile_unmanaged:
print(line, end="")
# Check if something happened
self.assertNotEmpty(line)
print('### ip monitor dev unmanaged0 END')
def test_keep_untracked_addresses(self):
# Add an unmanaged interface with an up address