From b088c3d3fc3a7a3a659ec0fe903a29cabd66dc49 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 3 Jul 2023 16:00:20 +0900 Subject: [PATCH 1/4] network: constify several functions --- src/network/networkd-util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h index f75fb1f8685..9c360f55264 100644 --- a/src/network/networkd-util.h +++ b/src/network/networkd-util.h @@ -70,7 +70,7 @@ int network_config_state_to_string_alloc(NetworkConfigState s, char **ret); \ t->state = (t->state & ~mask) | (value & mask); \ } \ - static inline bool name##_exists(type *t) { \ + static inline bool name##_exists(const type *t) { \ assert(t); \ \ if ((t->state & (NETWORK_CONFIG_STATE_CONFIGURING | \ @@ -90,7 +90,7 @@ int network_config_state_to_string_alloc(NetworkConfigState s, char **ret); NETWORK_CONFIG_STATE_REQUESTING, \ 0); \ } \ - static inline bool name##_is_requesting(type *t) { \ + static inline bool name##_is_requesting(const type *t) { \ assert(t); \ return FLAGS_SET(t->state, NETWORK_CONFIG_STATE_REQUESTING); \ } \ @@ -115,7 +115,7 @@ int network_config_state_to_string_alloc(NetworkConfigState s, char **ret); static inline void name##_unmark(type *t) { \ name##_update_state(t, NETWORK_CONFIG_STATE_MARKED, 0); \ } \ - static inline bool name##_is_marked(type *t) { \ + static inline bool name##_is_marked(const type *t) { \ assert(t); \ return FLAGS_SET(t->state, NETWORK_CONFIG_STATE_MARKED); \ } \ From 6e8477edd3a988357ad5f5fa6610904d44ec402c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 3 Jul 2023 15:43:53 +0900 Subject: [PATCH 2/4] network: delay to configure address until it is removed on reconfigure When we request an address that already exists and is under removing, we need to wait for the address being removed. Otherwise, configuration of a route whose preferred source is the address will fail. Fixes #28009. Replaces #28088. --- src/network/networkd-address.c | 3 +++ src/network/networkd-util.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 5c87a6c9c76..57a9ceb2298 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1158,6 +1158,9 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) { if (!link_is_ready_to_configure(link, false)) return false; + if (address_is_removing(address)) + return false; + if (!ipv4acd_bound(address)) return false; diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h index 9c360f55264..8ffe4b5b5be 100644 --- a/src/network/networkd-util.h +++ b/src/network/networkd-util.h @@ -125,6 +125,10 @@ int network_config_state_to_string_alloc(NetworkConfigState s, char **ret); NETWORK_CONFIG_STATE_REMOVING, \ NETWORK_CONFIG_STATE_REMOVING); \ } \ + static inline bool name##_is_removing(const type *t) { \ + assert(t); \ + return FLAGS_SET(t->state, NETWORK_CONFIG_STATE_REMOVING); \ + } \ static inline void name##_enter_removed(type *t) { \ name##_update_state(t, \ NETWORK_CONFIG_STATE_CONFIGURED | \ From 7e30527806956b7240ca7bf8d92038170fda44d0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 3 Jul 2023 16:03:50 +0900 Subject: [PATCH 3/4] test-network: check route more strictly --- test/test-network/systemd-networkd-tests.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 9f55456fa4b..1d426ee9798 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2973,9 +2973,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): output = check_output('ip -6 route list dev bond199') print(output) - self.assertRegex(output, 'abcd::/16') - self.assertRegex(output, 'src') - self.assertRegex(output, '2001:1234:56:8f63::2') + self.assertIn('abcd::/16 via 2001:1234:56:8f63::1:1 proto static src 2001:1234:56:8f63::2', output) def test_ip_link_mac_address(self): copy_network_unit('25-address-link-section.network', '12-dummy.netdev') From e4948bb2cdd1c8d1b6fc357e5b817170612aae33 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 3 Jul 2023 16:04:30 +0900 Subject: [PATCH 4/4] test-network: add test for static route with preferred source This adds possible reproducer for issue #28009 (though, the issue is highly racy, hence this may not trigger the issue reliably). --- .../conf/25-route-preferred-source.network | 12 ++++++++++++ test/test-network/systemd-networkd-tests.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 test/test-network/conf/25-route-preferred-source.network diff --git a/test/test-network/conf/25-route-preferred-source.network b/test/test-network/conf/25-route-preferred-source.network new file mode 100644 index 00000000000..5a55460349b --- /dev/null +++ b/test/test-network/conf/25-route-preferred-source.network @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Match] +Name=dummy98 + +[Network] +Address=2001:1234:56:8f63::1/64 +IPv6AcceptRA=no + +[Route] +Destination=abcd::/16 +Gateway=2001:1234:56:8f63::1:1 +PreferredSource=2001:1234:56:8f63::1 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 1d426ee9798..902614712e8 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2975,6 +2975,21 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): print(output) self.assertIn('abcd::/16 via 2001:1234:56:8f63::1:1 proto static src 2001:1234:56:8f63::2', output) + def test_route_preferred_source_with_existing_address(self): + # See issue #28009. + copy_network_unit('25-route-preferred-source.network', '12-dummy.netdev') + start_networkd() + + for i in range(3): + if i != 0: + networkctl_reconfigure('dummy98') + + self.wait_online(['dummy98:routable']) + + output = check_output('ip -6 route list dev dummy98') + print(output) + self.assertIn('abcd::/16 via 2001:1234:56:8f63::1:1 proto static src 2001:1234:56:8f63::1', output) + def test_ip_link_mac_address(self): copy_network_unit('25-address-link-section.network', '12-dummy.netdev') start_networkd()