diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 5ad9a846f03..fa80bdc51bb 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1081,11 +1081,11 @@ IPv6Token=prefixstable:2002:da8:1:: Takes a boolean. If true the kernel manage temporary addresses created from this one as template on behalf of Privacy Extensions - RFC 3041. For this to become + RFC 3041. For this to become active, the use_tempaddr sysctl setting has to be set to a value greater than zero. The given address needs to have a prefix length of 64. This flag allows using privacy extensions in a manually configured network, just like if stateless auto-configuration - was active. Defaults to false. + was active. Defaults to false. @@ -2056,6 +2056,13 @@ IPv6Token=prefixstable:2002:da8:1:: addresses. Defaults to unset. + + + ManageTemporaryAddress= + + As in the [Address] section, but defaults to true. + + diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 89b22c35e36..9571221da29 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -365,11 +365,11 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin return 1; } -static int dhcp6_set_pd_address(Link *link, - const union in_addr_union *prefix, - uint8_t prefix_len, - uint32_t lifetime_preferred, - uint32_t lifetime_valid) { +static int dhcp6_set_pd_address( + Link *link, + const union in_addr_union *prefix, + uint32_t lifetime_preferred, + uint32_t lifetime_valid) { _cleanup_(address_freep) Address *address = NULL; Address *ret; @@ -396,10 +396,11 @@ static int dhcp6_set_pd_address(Link *link, return log_link_warning_errno(link, r, "Failed to generate EUI64 address for acquired DHCPv6 delegated prefix: %m"); } - address->prefixlen = prefix_len; + address->prefixlen = 64; address->family = AF_INET6; address->cinfo.ifa_prefered = lifetime_preferred; address->cinfo.ifa_valid = lifetime_valid; + SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address); r = address_configure(address, link, dhcp6_pd_address_handler, true, &ret); if (r < 0) @@ -416,8 +417,13 @@ static int dhcp6_set_pd_address(Link *link, return 0; } -static int dhcp6_pd_assign_prefix(Link *link, const union in_addr_union *prefix, const union in_addr_union *pd_prefix, - uint8_t prefix_len, uint32_t lifetime_preferred, uint32_t lifetime_valid) { +static int dhcp6_pd_assign_prefix( + Link *link, + const union in_addr_union *prefix, + const union in_addr_union *pd_prefix, + uint32_t lifetime_preferred, + uint32_t lifetime_valid) { + int r; assert(link); @@ -425,7 +431,7 @@ static int dhcp6_pd_assign_prefix(Link *link, const union in_addr_union *prefix, assert(prefix); if (link->network->dhcp6_pd_announce) { - r = radv_add_prefix(link, &prefix->in6, prefix_len, lifetime_preferred, lifetime_valid); + r = radv_add_prefix(link, &prefix->in6, 64, lifetime_preferred, lifetime_valid); if (r < 0) return r; } @@ -434,7 +440,7 @@ static int dhcp6_pd_assign_prefix(Link *link, const union in_addr_union *prefix, if (r < 0) return r; - r = dhcp6_set_pd_address(link, prefix, prefix_len, lifetime_preferred, lifetime_valid); + r = dhcp6_set_pd_address(link, prefix, lifetime_preferred, lifetime_valid); if (r < 0) return r; @@ -559,7 +565,7 @@ static void dhcp6_pd_prefix_distribute(Link *dhcp6_link, } (void) in_addr_to_string(AF_INET6, &assigned_prefix, &assigned_buf); - r = dhcp6_pd_assign_prefix(link, &assigned_prefix, masked_pd_prefix, 64, + r = dhcp6_pd_assign_prefix(link, &assigned_prefix, masked_pd_prefix, lifetime_preferred, lifetime_valid); if (r < 0) { log_link_error_errno(link, r, "Unable to assign/update prefix %s/64: %m", diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 00ba043b23e..896a8840637 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -295,6 +295,7 @@ BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp6_pd_subnet_id, 0, offsetof(Network, dhcp6_pd_subnet_id) DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp6_pd_announce) DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign) +DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address) DHCPv6PrefixDelegation.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token) IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index a8d6c58ac4d..a74a1e946e5 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -361,6 +361,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp6_pd = -1, .dhcp6_pd_announce = true, .dhcp6_pd_assign = true, + .dhcp6_pd_manage_temporary_address = true, .dhcp6_pd_subnet_id = -1, .dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 656bf6c3669..bd419f6ef41 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -200,6 +200,7 @@ struct Network { int dhcp6_pd; bool dhcp6_pd_announce; bool dhcp6_pd_assign; + bool dhcp6_pd_manage_temporary_address; int64_t dhcp6_pd_subnet_id; union in_addr_union dhcp6_pd_token; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 3024c65713b..cc91437c164 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -143,6 +143,7 @@ RouteMetric= SubnetId= Announce= Assign= +ManageTemporaryAddress= Token= [Route] Destination=