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 /src/network/networkd-dhcp-prefix-delegation.c | |
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
Diffstat (limited to 'src/network/networkd-dhcp-prefix-delegation.c')
-rw-r--r-- | src/network/networkd-dhcp-prefix-delegation.c | 56 |
1 files changed, 48 insertions, 8 deletions
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; } |