From 38488babe791639860068905177a415822b6b98b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 20 Feb 2022 11:23:18 +0900 Subject: [PATCH] network: dhcp-pd: fix prefix length of address assigned to upstream interface This effectively revert ab0c82d9f749cc397a6b7e0327ddb2c08cd7d7e0. I have no idea why I did that... Fixes #22559. --- src/network/networkd-address-generation.c | 4 +- src/network/networkd-address-generation.h | 2 +- src/network/networkd-dhcp-prefix-delegation.c | 87 ++++++------------- test/test-network/systemd-networkd-tests.py | 23 ++--- 4 files changed, 41 insertions(+), 75 deletions(-) diff --git a/src/network/networkd-address-generation.c b/src/network/networkd-address-generation.c index 85110355a1..2dedcf3723 100644 --- a/src/network/networkd-address-generation.c +++ b/src/network/networkd-address-generation.c @@ -252,8 +252,8 @@ static int generate_addresses( return 0; } -int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) { - return generate_addresses(link, link->network->dhcp_pd_tokens, &DHCP_PD_APP_ID, prefix, prefixlen, ret); +int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret) { + return generate_addresses(link, link->network->dhcp_pd_tokens, &DHCP_PD_APP_ID, prefix, 64, ret); } int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) { diff --git a/src/network/networkd-address-generation.h b/src/network/networkd-address-generation.h index e9c924eb97..901b2ec4bf 100644 --- a/src/network/networkd-address-generation.h +++ b/src/network/networkd-address-generation.h @@ -7,7 +7,7 @@ typedef struct Link Link; -int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); +int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret); int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); int radv_generate_addresses(Link *link, Set *tokens, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index 949c74bd58..7be9713d46 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -307,7 +307,7 @@ static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link * return 1; } -static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, usec_t lifetime_usec) { +static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, usec_t lifetime_usec) { _cleanup_(route_freep) Route *route = NULL; Route *existing; int r; @@ -326,7 +326,7 @@ static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, uint route->source = NETWORK_CONFIG_SOURCE_DHCP_PD; route->family = AF_INET6; route->dst.in6 = *prefix; - route->dst_prefixlen = prefixlen; + route->dst_prefixlen = 64; route->protocol = RTPROT_DHCP; route->priority = link->network->dhcp_pd_route_metric; route->lifetime_usec = lifetime_usec; @@ -386,7 +386,6 @@ static void log_dhcp_pd_address(Link *link, const Address *address) { static int dhcp_pd_request_address( Link *link, const struct in6_addr *prefix, - uint8_t prefixlen, usec_t lifetime_preferred_usec, usec_t lifetime_valid_usec) { @@ -401,7 +400,7 @@ static int dhcp_pd_request_address( if (!link->network->dhcp_pd_assign) return 0; - r = dhcp_pd_generate_addresses(link, prefix, prefixlen, &addresses); + r = dhcp_pd_generate_addresses(link, prefix, &addresses); if (r < 0) return log_link_warning_errno(link, r, "Failed to generate addresses for acquired DHCP delegated prefix: %m"); @@ -416,11 +415,10 @@ static int dhcp_pd_request_address( address->source = NETWORK_CONFIG_SOURCE_DHCP_PD; address->family = AF_INET6; address->in_addr.in6 = *a; - address->prefixlen = prefixlen; + address->prefixlen = 64; address->lifetime_preferred_usec = lifetime_preferred_usec; address->lifetime_valid_usec = lifetime_valid_usec; - if (prefixlen == 64) - SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp_pd_manage_temporary_address); + SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp_pd_manage_temporary_address); address->route_metric = link->network->dhcp_pd_route_metric; log_dhcp_pd_address(link, address); @@ -531,7 +529,8 @@ static int dhcp_pd_assign_subnet_prefix( const struct in6_addr *pd_prefix, uint8_t pd_prefix_len, usec_t lifetime_preferred_usec, - usec_t lifetime_valid_usec) { + usec_t lifetime_valid_usec, + bool is_uplink) { _cleanup_free_ char *buf = NULL; struct in6_addr prefix; @@ -548,20 +547,24 @@ static int dhcp_pd_assign_subnet_prefix( (void) in6_addr_prefix_to_string(&prefix, 64, &buf); if (link_radv_enabled(link) && link->network->dhcp_pd_announce) { - r = radv_add_prefix(link, &prefix, 64, lifetime_preferred_usec, lifetime_valid_usec); - if (r < 0) - return log_link_warning_errno(link, r, - "Failed to assign/update prefix %s to IPv6 Router Advertisement: %m", - strna(buf)); + if (is_uplink) + log_link_debug(link, "Ignoring Announce= setting on upstream interface."); + else { + r = radv_add_prefix(link, &prefix, 64, lifetime_preferred_usec, lifetime_valid_usec); + if (r < 0) + return log_link_warning_errno(link, r, + "Failed to assign/update prefix %s to IPv6 Router Advertisement: %m", + strna(buf)); + } } - r = dhcp_pd_request_route(link, &prefix, 64, lifetime_valid_usec); + r = dhcp_pd_request_route(link, &prefix, lifetime_valid_usec); if (r < 0) return log_link_warning_errno(link, r, "Failed to assign/update route for prefix %s: %m", strna(buf)); - r = dhcp_pd_request_address(link, &prefix, 64, lifetime_preferred_usec, lifetime_valid_usec); + r = dhcp_pd_request_address(link, &prefix, lifetime_preferred_usec, lifetime_valid_usec); if (r < 0) return log_link_warning_errno(link, r, "Failed to assign/update address for prefix %s: %m", @@ -577,41 +580,6 @@ static int dhcp_pd_assign_subnet_prefix( return 1; } -static int dhcp_pd_assign_prefix_on_uplink( - Link *link, - const struct in6_addr *pd_prefix, - uint8_t pd_prefix_len, - usec_t lifetime_preferred_usec, - usec_t lifetime_valid_usec) { - - _cleanup_free_ char *buf = NULL; - int r; - - assert(link); - assert(link->network); - assert(pd_prefix); - - (void) in6_addr_prefix_to_string(pd_prefix, pd_prefix_len, &buf); - - if (link->network->dhcp_pd_announce) - log_link_debug(link, "Ignoring Announce= setting on upstream interface."); - - r = dhcp_pd_request_route(link, pd_prefix, pd_prefix_len, lifetime_valid_usec); - if (r < 0) - return log_link_warning_errno(link, r, - "Failed to assign/update route for prefix %s: %m", - strna(buf)); - - r = dhcp_pd_request_address(link, pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); - if (r < 0) - return log_link_warning_errno(link, r, - "Failed to assign/update address for prefix %s: %m", - strna(buf)); - - log_link_debug(link, "Assigned prefix %s", strna(buf)); - return 1; -} - static int dhcp_pd_prepare(Link *link) { if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) return 0; @@ -954,19 +922,15 @@ static int dhcp4_pd_assign_subnet_prefix(Link *link, Link *uplink) { return r; if (streq_ptr(uplink->dhcp4_6rd_tunnel_name, link->ifname)) { - r = dhcp_pd_assign_prefix_on_uplink(link, &pd_prefix, pd_prefixlen, lifetime_usec, lifetime_usec); - if (r < 0) - return r; - r = dhcp4_pd_request_default_gateway_on_6rd_tunnel(link, &br_addresses[0], lifetime_usec); if (r < 0) return r; - } else { - r = dhcp_pd_assign_subnet_prefix(link, &pd_prefix, pd_prefixlen, lifetime_usec, lifetime_usec); - if (r < 0) - return r; } + r = dhcp_pd_assign_subnet_prefix(link, &pd_prefix, pd_prefixlen, lifetime_usec, lifetime_usec, /* is_uplink = */ false); + if (r < 0) + return r; + return dhcp_pd_finalize(link); } @@ -1127,10 +1091,9 @@ static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) { lifetime_preferred_usec = usec_add(lifetime_preferred_sec * USEC_PER_SEC, timestamp_usec); lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec); - if (link == uplink) - r = dhcp_pd_assign_prefix_on_uplink(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); - else - r = dhcp_pd_assign_subnet_prefix(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); + r = dhcp_pd_assign_subnet_prefix(link, &pd_prefix, pd_prefix_len, + lifetime_preferred_usec, lifetime_valid_usec, + /* is_uplink = */ link == uplink); if (r < 0) return r; } diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index e8729ae8af..35c9efd77d 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5273,7 +5273,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): # dummy99: auto -> 0x03 (No address assignment) # veth97: 0x08 # veth98: 0x09 - # veth99: 0x10 (ignored, as it is upstream) + # veth99: 0x10 print('### ip -6 address show dev veth99 scope global') output = check_output('ip -6 address show dev veth99 scope global') @@ -5281,9 +5281,12 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): # IA_NA self.assertRegex(output, 'inet6 3ffe:501:ffff:100::[0-9]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') # address in IA_PD (Token=static) - self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/56 (metric 256 |)scope global dynamic') + self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic') # address in IA_PD (Token=eui64) - self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1034:56ff:fe78:9abc/56 (metric 256 |)scope global dynamic') + self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic') + # address in IA_PD (temporary) + # Note that the temporary addresses may appear after the link enters configured state + self.wait_address('veth99', 'inet6 3ffe:501:ffff:[2-9a-f]10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6') print('### ip -6 address show dev test1 scope global') output = check_output('ip -6 address show dev test1 scope global') @@ -5291,7 +5294,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): # address in IA_PD (Token=static) self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # address in IA_PD (temporary) - # Note that the temporary addresses may appear after the link enters configured state self.wait_address('test1', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6') print('### ip -6 address show dev dummy98 scope global') @@ -5356,7 +5358,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print('### ip -6 route show dev veth99') output = check_output('ip -6 route show dev veth99') print(output) - self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]00::/56 proto kernel metric [0-9]* expires') + self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]10::/64 proto kernel metric [0-9]* expires') print('### ip -6 route show dev test1') output = check_output('ip -6 route show dev test1') @@ -5448,7 +5450,8 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): # test1: 0x00 # dummy97: 0x01 (The link will appear later) # dummy98: 0x02 - # dummy99: auto -> 0x03 (No address assignment) + # dummy99: auto -> 0x0[34] (No address assignment) + # 6rd-XXX: auto -> 0x0[34] # veth97: 0x08 # veth98: 0x09 # veth99: 0x10 @@ -5489,7 +5492,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): output = check_output('ip -6 address show dev dummy99 scope global') print(output) # Assign=no - self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03') + self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+0[34]') print('### ip -6 address show dev veth97 scope global') output = check_output('ip -6 address show dev veth97 scope global') @@ -5554,7 +5557,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print('### ip -6 route show dev dummy99') output = check_output('ip -6 route show dev dummy99') print(output) - self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires') + self.assertRegex(output, '2001:db8:6464:[0-9a-f]+0[34]::/64 proto dhcp metric [0-9]* expires') print('### ip -6 route show dev veth97') output = check_output('ip -6 route show dev veth97') @@ -5601,13 +5604,13 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print('### ip -6 address show dev {}'.format(tunnel_name)) output = check_output('ip -6 address show dev {}'.format(tunnel_name)) print(output) - self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/56 (metric 256 |)scope global dynamic') + self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+0[34]:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global dynamic') self.assertRegex(output, 'inet6 ::10.100.100.[0-9]+/96 scope global') print('### ip -6 route show dev {}'.format(tunnel_name)) output = check_output('ip -6 route show dev {}'.format(tunnel_name)) print(output) - self.assertRegex(output, '2001:db8:6464:[0-9a-f]+00::/56 proto kernel metric [0-9]* expires') + self.assertRegex(output, '2001:db8:6464:[0-9a-f]+0[34]::/64 proto kernel metric [0-9]* expires') self.assertRegex(output, '::/96 proto kernel metric [0-9]*') print('### ip -6 route show default') -- 2.25.1