mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-27 14:03:43 +03:00
Merge pull request #22611 from yuwata/network-activation-policy-stacked-netdevs
network: make activation policy also work for stacked netdevs
This commit is contained in:
commit
6b3211c15e
@ -643,6 +643,11 @@ static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
|
|||||||
|
|
||||||
if (link->set_link_messages > 0)
|
if (link->set_link_messages > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* If stacked netdevs are created before the underlying interface being activated, then
|
||||||
|
* the activation policy for the netdevs are ignored. See issue #22593. */
|
||||||
|
if (!link->activated)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NETDEV_VTABLE(netdev)->is_ready_to_create)
|
if (NETDEV_VTABLE(netdev)->is_ready_to_create)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
[Match]
|
[Match]
|
||||||
Name=test1
|
Name=test1
|
||||||
|
Name=vlan99
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
Address=192.168.10.30/24
|
Address=192.168.10.30/24
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
[NetDev]
|
|
||||||
Name=vlan6
|
|
||||||
Kind=vlan
|
|
||||||
MTUBytes=1500
|
|
||||||
|
|
||||||
[VLAN]
|
|
||||||
Id=6
|
|
@ -1,7 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
[Match]
|
|
||||||
Name=vlan6
|
|
||||||
|
|
||||||
[Network]
|
|
||||||
IPv6AcceptRA=false
|
|
||||||
Address=100.100.100.2/24
|
|
@ -609,11 +609,13 @@ class Utilities():
|
|||||||
needle = f'{link}: Bringing link {state}'
|
needle = f'{link}: Bringing link {state}'
|
||||||
flag = state.upper()
|
flag = state.upper()
|
||||||
for iteration in range(timeout+1):
|
for iteration in range(timeout+1):
|
||||||
|
if iteration != 0:
|
||||||
|
time.sleep(1)
|
||||||
|
if not link_exists(link):
|
||||||
|
continue
|
||||||
output = check_output('journalctl _SYSTEMD_INVOCATION_ID=' + invocation_id)
|
output = check_output('journalctl _SYSTEMD_INVOCATION_ID=' + invocation_id)
|
||||||
if needle in output and flag in check_output(f'ip link show {link}'):
|
if needle in output and flag in check_output(f'ip link show {link}'):
|
||||||
return True
|
return True
|
||||||
if iteration < timeout:
|
|
||||||
time.sleep(1)
|
|
||||||
if fail_assert:
|
if fail_assert:
|
||||||
self.fail(f'Timed out waiting for {link} activated.')
|
self.fail(f'Timed out waiting for {link} activated.')
|
||||||
return False
|
return False
|
||||||
@ -638,13 +640,14 @@ class Utilities():
|
|||||||
setup_state = r'\S+'
|
setup_state = r'\S+'
|
||||||
|
|
||||||
for secs in range(setup_timeout + 1):
|
for secs in range(setup_timeout + 1):
|
||||||
|
if secs != 0:
|
||||||
|
time.sleep(1)
|
||||||
|
if not link_exists(link):
|
||||||
|
continue
|
||||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', link, env=env)
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', link, env=env)
|
||||||
print(output)
|
print(output)
|
||||||
if re.search(rf'(?m)^\s*State:\s+{operstate}\s+\({setup_state}\)\s*$', output):
|
if re.search(rf'(?m)^\s*State:\s+{operstate}\s+\({setup_state}\)\s*$', output):
|
||||||
return True
|
return True
|
||||||
# don't bother sleeping if time is up
|
|
||||||
if secs < setup_timeout:
|
|
||||||
time.sleep(1)
|
|
||||||
if fail_assert:
|
if fail_assert:
|
||||||
self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
|
self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
|
||||||
return False
|
return False
|
||||||
@ -2053,6 +2056,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
'test1',
|
'test1',
|
||||||
'veth-peer',
|
'veth-peer',
|
||||||
'veth99',
|
'veth99',
|
||||||
|
'vlan99',
|
||||||
'vrf99',
|
'vrf99',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2060,6 +2064,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
'11-dummy.netdev',
|
'11-dummy.netdev',
|
||||||
'12-dummy.netdev',
|
'12-dummy.netdev',
|
||||||
'12-dummy.network',
|
'12-dummy.network',
|
||||||
|
'21-vlan.netdev',
|
||||||
|
'21-vlan-test1.network',
|
||||||
'23-active-slave.network',
|
'23-active-slave.network',
|
||||||
'24-keep-configuration-static.network',
|
'24-keep-configuration-static.network',
|
||||||
'24-search-domain.network',
|
'24-search-domain.network',
|
||||||
@ -3115,10 +3121,12 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
|
self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
|
||||||
self.wait_operstate('test1', 'routable')
|
self.wait_operstate('test1', 'routable')
|
||||||
|
|
||||||
def _test_activation_policy(self, test):
|
def _test_activation_policy(self, test, interface):
|
||||||
conffile = '25-activation-policy.network'
|
conffile = '25-activation-policy.network'
|
||||||
if test:
|
if test:
|
||||||
conffile = f'{conffile}.d/{test}.conf'
|
conffile = f'{conffile}.d/{test}.conf'
|
||||||
|
if interface == 'vlan99':
|
||||||
|
copy_unit_to_networkd_unit_path('21-vlan.netdev', '21-vlan-test1.network')
|
||||||
copy_unit_to_networkd_unit_path('11-dummy.netdev', conffile, dropins=False)
|
copy_unit_to_networkd_unit_path('11-dummy.netdev', conffile, dropins=False)
|
||||||
start_networkd()
|
start_networkd()
|
||||||
|
|
||||||
@ -3128,36 +3136,38 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
next_up = not expect_up
|
next_up = not expect_up
|
||||||
|
|
||||||
if test.endswith('down'):
|
if test.endswith('down'):
|
||||||
self.wait_activated('test1')
|
self.wait_activated(interface)
|
||||||
|
|
||||||
for iteration in range(4):
|
for iteration in range(4):
|
||||||
with self.subTest(iteration=iteration, expect_up=expect_up):
|
with self.subTest(iteration=iteration, expect_up=expect_up):
|
||||||
operstate = 'routable' if expect_up else 'off'
|
operstate = 'routable' if expect_up else 'off'
|
||||||
setup_state = 'configured' if expect_up else ('configuring' if iteration == 0 else None)
|
setup_state = 'configured' if expect_up else ('configuring' if iteration == 0 else None)
|
||||||
self.wait_operstate('test1', operstate, setup_state=setup_state, setup_timeout=20)
|
self.wait_operstate(interface, operstate, setup_state=setup_state, setup_timeout=20)
|
||||||
|
|
||||||
if expect_up:
|
if expect_up:
|
||||||
self.assertIn('UP', check_output('ip link show test1'))
|
self.assertIn('UP', check_output(f'ip link show {interface}'))
|
||||||
self.assertIn('192.168.10.30/24', check_output('ip address show test1'))
|
self.assertIn('192.168.10.30/24', check_output(f'ip address show {interface}'))
|
||||||
self.assertIn('default via 192.168.10.1', check_output('ip route show dev test1'))
|
self.assertIn('default via 192.168.10.1', check_output(f'ip route show dev {interface}'))
|
||||||
else:
|
else:
|
||||||
self.assertIn('DOWN', check_output('ip link show test1'))
|
self.assertIn('DOWN', check_output(f'ip link show {interface}'))
|
||||||
|
|
||||||
if next_up:
|
if next_up:
|
||||||
check_output('ip link set dev test1 up')
|
check_output(f'ip link set dev {interface} up')
|
||||||
else:
|
else:
|
||||||
check_output('ip link set dev test1 down')
|
check_output(f'ip link set dev {interface} down')
|
||||||
expect_up = initial_up if always else next_up
|
expect_up = initial_up if always else next_up
|
||||||
next_up = not next_up
|
next_up = not next_up
|
||||||
if always:
|
if always:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def test_activation_policy(self):
|
def test_activation_policy(self):
|
||||||
for test in ['up', 'always-up', 'manual', 'always-down', 'down', '']:
|
for interface in ['test1', 'vlan99']:
|
||||||
with self.subTest(test=test):
|
with self.subTest(interface=interface):
|
||||||
self.setUp()
|
for test in ['up', 'always-up', 'manual', 'always-down', 'down', '']:
|
||||||
self._test_activation_policy(test)
|
with self.subTest(test=test):
|
||||||
self.tearDown()
|
self.setUp()
|
||||||
|
self._test_activation_policy(test, interface)
|
||||||
|
self.tearDown()
|
||||||
|
|
||||||
def _test_activation_policy_required_for_online(self, policy, required):
|
def _test_activation_policy_required_for_online(self, policy, required):
|
||||||
conffile = '25-activation-policy.network'
|
conffile = '25-activation-policy.network'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user