summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-12-05 13:38:48 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-12-07 11:46:37 +0100
commitab0c82d9f749cc397a6b7e0327ddb2c08cd7d7e0 (patch)
tree13fc9817a9fe58bec995f1d579e8d0413ae14b54
parentnetwork: dhcp6pd: do not check Announce= setting when the link does not suppo... (diff)
downloadsystemd-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.c4
-rw-r--r--src/network/networkd-address-generation.h2
-rw-r--r--src/network/networkd-dhcp-prefix-delegation.c56
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py12
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')