From 706cd859370b118c3267643e73890c416ff91d9f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 Nov 2023 02:39:33 +0900 Subject: [PATCH 1/4] network/dhcp-pd: use correct flag when DHCPv4 6rd is enabled Previously, Link.dhcp6_configured flag was unconditionally used even if the route is configured based on the DHCPv4 protocol. Follow-up for a27588d4e7f780243a1828e2af56562f9d779412 and e49bad0179cb670edeac12ef062887af0ac4c8c5. --- src/network/networkd-dhcp-prefix-delegation.c | 12 ++++++++---- src/network/networkd-link.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index 56bbc4acc5..af2fe9efcd 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -665,7 +665,8 @@ static int dhcp_request_unreachable_route( NetworkConfigSource source, const union in_addr_union *server_address, unsigned *counter, - route_netlink_handler_t callback) { + route_netlink_handler_t callback, + bool *configured) { _cleanup_(route_freep) Route *route = NULL; Route *existing; @@ -677,6 +678,7 @@ static int dhcp_request_unreachable_route( assert(server_address); assert(counter); assert(callback); + assert(configured); if (prefixlen >= 64) { log_link_debug(link, "Not adding a blocking route for DHCP delegated prefix %s since the prefix has length >= 64.", @@ -699,7 +701,7 @@ static int dhcp_request_unreachable_route( route->lifetime_usec = lifetime_usec; if (route_get(link->manager, NULL, route, &existing) < 0) - link->dhcp6_configured = false; + *configured = false; else route_unmark(existing); @@ -720,7 +722,8 @@ static int dhcp4_request_unreachable_route( return dhcp_request_unreachable_route(link, addr, prefixlen, lifetime_usec, NETWORK_CONFIG_SOURCE_DHCP4, server_address, - &link->dhcp4_messages, dhcp4_unreachable_route_handler); + &link->dhcp4_messages, dhcp4_unreachable_route_handler, + &link->dhcp4_configured); } static int dhcp6_request_unreachable_route( @@ -732,7 +735,8 @@ static int dhcp6_request_unreachable_route( return dhcp_request_unreachable_route(link, addr, prefixlen, lifetime_usec, NETWORK_CONFIG_SOURCE_DHCP6, server_address, - &link->dhcp6_messages, dhcp6_unreachable_route_handler); + &link->dhcp6_messages, dhcp6_unreachable_route_handler, + &link->dhcp6_configured); } static int dhcp_pd_prefix_add(Link *link, const struct in6_addr *prefix, uint8_t prefixlen) { diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 8bbbc4ec85..938bbf482e 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -127,7 +127,7 @@ typedef struct Link { sd_dhcp_lease *dhcp_lease; char *lease_file; unsigned dhcp4_messages; - bool dhcp4_configured:1; + bool dhcp4_configured; char *dhcp4_6rd_tunnel_name; Hashmap *ipv4acd_by_address; From f5e1781a9eaaca3a7249e8145ecb02ed25128c86 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 Nov 2023 02:28:56 +0900 Subject: [PATCH 2/4] network/dhcp6: use link_check_address_ready() at one more place --- src/network/networkd-dhcp6.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index cc2c466cdd..6d38840ccb 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -96,8 +96,6 @@ static int dhcp6_address_ready_callback(Address *address) { } int dhcp6_check_ready(Link *link) { - bool has_ready = false; - Address *address; int r; assert(link); @@ -107,16 +105,9 @@ int dhcp6_check_ready(Link *link) { return 0; } - SET_FOREACH(address, link->addresses) { - if (address->source != NETWORK_CONFIG_SOURCE_DHCP6) - continue; - if (address_is_ready(address)) { - has_ready = true; - break; - } - } + if (!link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP6)) { + Address *address; - if (!has_ready) { SET_FOREACH(address, link->addresses) if (address->source == NETWORK_CONFIG_SOURCE_DHCP6) address->callback = dhcp6_address_ready_callback; From fc4aa64c2d7bf1443bf30b66d334e33addb0d27a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 Nov 2023 02:30:20 +0900 Subject: [PATCH 3/4] network/dhcp6: skip to check existence of DHCPv6 address when UseAddress=no Follow-up for 1536b7b2d00819615bf8eba194de7ccd20c3689f and 5f950e56211a90b21e8096ebf27c9c2b8afbd231. Fixes #29979. --- src/network/networkd-dhcp6.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 6d38840ccb..ee20d0ed50 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -99,13 +99,15 @@ int dhcp6_check_ready(Link *link) { int r; assert(link); + assert(link->network); if (link->dhcp6_messages > 0) { log_link_debug(link, "%s(): DHCPv6 addresses and routes are not set.", __func__); return 0; } - if (!link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP6)) { + if (link->network->dhcp6_use_address && + !link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP6)) { Address *address; SET_FOREACH(address, link->addresses) From 1805e2cb05f634903ff81ba71f1cbab32c7581c6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 Nov 2023 03:30:00 +0900 Subject: [PATCH 4/4] test-network: add test case for issue #29979 --- .../conf/25-dhcp6pd-upstream.network | 2 ++ .../with-address.conf | 6 ++++++ test/test-network/systemd-networkd-tests.py | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/test-network/conf/25-dhcp6pd-upstream.network.d/with-address.conf diff --git a/test/test-network/conf/25-dhcp6pd-upstream.network b/test/test-network/conf/25-dhcp6pd-upstream.network index 4b8cd7d324..01f0e9e6d5 100644 --- a/test/test-network/conf/25-dhcp6pd-upstream.network +++ b/test/test-network/conf/25-dhcp6pd-upstream.network @@ -10,6 +10,7 @@ DHCPPrefixDelegation=yes [DHCPv6] WithoutRA=solicit +UseAddress=no [DHCPPrefixDelegation] UplinkInterface=:self @@ -17,3 +18,4 @@ SubnetId=10 Announce=no Token=eui64 Token=::1a:2b:3c:4d +Assign=no diff --git a/test/test-network/conf/25-dhcp6pd-upstream.network.d/with-address.conf b/test/test-network/conf/25-dhcp6pd-upstream.network.d/with-address.conf new file mode 100644 index 0000000000..451475509d --- /dev/null +++ b/test/test-network/conf/25-dhcp6pd-upstream.network.d/with-address.conf @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[DHCPv6] +UseAddress=yes + +[DHCPPrefixDelegation] +Assign=yes diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index c77a0e0eb2..041dfd313b 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -6086,7 +6086,8 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): '11-dummy.netdev', '25-dhcp-pd-downstream-test1.network', '25-dhcp-pd-downstream-dummy97.network', '12-dummy.netdev', '25-dhcp-pd-downstream-dummy98.network', - '13-dummy.netdev', '25-dhcp-pd-downstream-dummy99.network') + '13-dummy.netdev', '25-dhcp-pd-downstream-dummy99.network', + copy_dropins=False) self.setup_nftset('addr6', 'ipv6_addr') self.setup_nftset('network6', 'ipv6_addr', 'flags interval;') @@ -6095,8 +6096,14 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): start_networkd() self.wait_online(['veth-peer:routable']) start_isc_dhcpd(conf_file='isc-dhcpd-dhcp6pd.conf', ipv='-6') - self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded', - 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) + self.wait_online(['veth99:degraded']) + + # First, test UseAddress=no and Assign=no (issue #29979). + # Note, due to the bug #29701, this test must be done at first. + print('### ip -6 address show dev veth99 scope global') + output = check_output('ip -6 address show dev veth99 scope global') + print(output) + self.assertNotIn('inet6 3ffe:501:ffff', output) # Check DBus assigned prefix information to veth99 prefixInfo = get_dhcp6_prefix('veth99') @@ -6114,6 +6121,11 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): self.assertGreater(prefixInfo['PreferredLifetimeUSec'], 0) self.assertGreater(prefixInfo['ValidLifetimeUSec'], 0) + copy_network_unit('25-dhcp6pd-upstream.network.d/with-address.conf') + networkctl_reload() + self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded', + 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) + print('### ip -6 address show dev veth-peer scope global') output = check_output('ip -6 address show dev veth-peer scope global') print(output)