diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-12-05 13:38:48 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-12-07 11:46:37 +0100 |
commit | ab0c82d9f749cc397a6b7e0327ddb2c08cd7d7e0 (patch) | |
tree | 13fc9817a9fe58bec995f1d579e8d0413ae14b54 | |
parent | network: dhcp6pd: do not check Announce= setting when the link does not suppo... (diff) | |
download | systemd-ab0c82d9f749cc397a6b7e0327ddb2c08cd7d7e0.tar.xz systemd-ab0c82d9f749cc397a6b7e0327ddb2c08cd7d7e0.zip |
network: dhcp6pd: assign addresses in the delegated prefix instead of a subnet prefix /64 on upstream interface
-rw-r--r-- | src/network/networkd-address-generation.c | 4 | ||||
-rw-r--r-- | src/network/networkd-address-generation.h | 2 | ||||
-rw-r--r-- | src/network/networkd-dhcp-prefix-delegation.c | 56 | ||||
-rwxr-xr-x | test/test-network/systemd-networkd-tests.py | 12 |
4 files changed, 56 insertions, 18 deletions
diff --git a/src/network/networkd-address-generation.c b/src/network/networkd-address-generation.c index 739ca97c2e..4cf4dd590e 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 dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret) { - return generate_addresses(link, link->network->dhcp6_pd_tokens, &DHCP6PD_APP_ID, prefix, 64, ret); +int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) { + return generate_addresses(link, link->network->dhcp6_pd_tokens, &DHCP6PD_APP_ID, prefix, prefixlen, 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 391a6ccc97..d8d9d6e8f0 100644 --- a/src/network/networkd-address-generation.h +++ b/src/network/networkd-address-generation.h @@ -7,7 +7,7 @@ typedef struct Link Link; -int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret); +int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, 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 61df70fd55..f32c2cbed5 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -296,7 +296,7 @@ static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link return 1; } -static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, usec_t lifetime_usec) { +static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, usec_t lifetime_usec) { _cleanup_(route_freep) Route *route = NULL; Route *existing; int r; @@ -315,7 +315,7 @@ static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, use route->source = NETWORK_CONFIG_SOURCE_DHCP6PD; route->family = AF_INET6; route->dst.in6 = *prefix; - route->dst_prefixlen = 64; + route->dst_prefixlen = prefixlen; route->protocol = RTPROT_DHCP; route->priority = link->network->dhcp6_pd_route_metric; route->lifetime_usec = lifetime_usec; @@ -375,6 +375,7 @@ static void log_dhcp6_pd_address(Link *link, const Address *address) { static int dhcp6_pd_request_address( Link *link, const struct in6_addr *prefix, + uint8_t prefixlen, usec_t lifetime_preferred_usec, usec_t lifetime_valid_usec) { @@ -389,7 +390,7 @@ static int dhcp6_pd_request_address( if (!link->network->dhcp6_pd_assign) return 0; - r = dhcp6_pd_generate_addresses(link, prefix, &addresses); + r = dhcp6_pd_generate_addresses(link, prefix, prefixlen, &addresses); if (r < 0) return log_link_warning_errno(link, r, "Failed to generate addresses for acquired DHCPv6 delegated prefix: %m"); @@ -404,10 +405,11 @@ static int dhcp6_pd_request_address( address->source = NETWORK_CONFIG_SOURCE_DHCP6PD; address->family = AF_INET6; address->in_addr.in6 = *a; - address->prefixlen = 64; + address->prefixlen = prefixlen; address->lifetime_preferred_usec = lifetime_preferred_usec; address->lifetime_valid_usec = lifetime_valid_usec; - SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address); + if (prefixlen == 64) + SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address); address->route_metric = link->network->dhcp6_pd_route_metric; log_dhcp6_pd_address(link, address); @@ -542,13 +544,13 @@ static int dhcp6_pd_assign_prefix( strna(buf)); } - r = dhcp6_pd_request_route(link, &prefix, lifetime_valid_usec); + r = dhcp6_pd_request_route(link, &prefix, 64, 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 = dhcp6_pd_request_address(link, &prefix, lifetime_preferred_usec, lifetime_valid_usec); + r = dhcp6_pd_request_address(link, &prefix, 64, 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", @@ -564,6 +566,41 @@ static int dhcp6_pd_assign_prefix( return 1; } +static int dhcp6_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->dhcp6_pd_announce) + log_link_debug(link, "Ignoring Announce= setting on upstream interface."); + + r = dhcp6_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 = dhcp6_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 dhcp6_pd_prepare(Link *link) { if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) return 0; @@ -778,7 +815,10 @@ static int dhcp6_pd_assign_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); - r = dhcp6_pd_assign_prefix(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); + if (link == uplink) + r = dhcp6_pd_assign_prefix_on_uplink(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); + else + r = dhcp6_pd_assign_prefix(link, &pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec); if (r < 0) return r; } diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 99eb89e3ee..f9af5f14d3 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5063,7 +5063,7 @@ class NetworkdDHCP6PDTests(unittest.TestCase, Utilities): dummy99: auto -> 0x03 (No address assignment) veth97: 0x08 veth98: 0x09 - veth99: 0x10 + veth99: 0x10 (ignored, as it is upstream) ''' print('### ip -6 address show dev veth99 scope global') @@ -5072,12 +5072,9 @@ class NetworkdDHCP6PDTests(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]10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') + self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/56 (metric 256 |)scope global dynamic') # address in IA_PD (Token=eui64) - self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1034:56ff:fe78:9abc/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('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') + self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1034:56ff:fe78:9abc/56 (metric 256 |)scope global dynamic') print('### ip -6 address show dev test1 scope global') output = check_output('ip -6 address show dev test1 scope global') @@ -5085,6 +5082,7 @@ class NetworkdDHCP6PDTests(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') @@ -5149,7 +5147,7 @@ class NetworkdDHCP6PDTests(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]10::/64 proto kernel metric [0-9]* expires') + self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]00::/56 proto kernel metric [0-9]* expires') print('### ip -6 route show dev test1') output = check_output('ip -6 route show dev test1') |