network: dhcp6: introduce UseDelegatedPrefix= setting and enable by default

Previously, the prefix delegation is enabled when at least one
downstream interfaces request it. But, when the DHCPv6 client on the
upstream interface is configured, some downstream interfaces may not
exist yet, nor have .network file assigned.

Also, if a system has thousands of interfaces, then the previous logic
introduce O(n^2) search.

This makes the prefix delegation is always enabled, except when it is
explicitly disabled. Hopefully, that should not break anything, as the
DHCPv6 server should ignore the prefix delegation request if the server
do not have any prefix to delegate.
This commit is contained in:
Yu Watanabe 2021-10-13 16:26:09 +09:00
parent 48538c19e5
commit 0f5ef9b62a
6 changed files with 21 additions and 24 deletions

View file

@ -2063,6 +2063,19 @@ Table=1234</programlisting></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseDelegatedPrefix=</varname></term>
<listitem>
<para>When true (the default), the client will request the DHCPv6 server to delegate
prefixes. If the server provides prefixes to be delegated, then subnets of the prefixes are
assigned to the interfaces which enables <varname>DHCPv6PrefixDelegation=</varname>.
See also <varname>DHCPv6PrefixDelegation=</varname> in [Network] section,
[DHCPv6PrefixDelegation] section, and
<ulink url="https://www.rfc-editor.org/rfc/rfc8415.html#section-6.3">RFC 8415</ulink>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<term><varname>UseDNS=</varname></term>

View file

@ -1423,25 +1423,6 @@ static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) {
return 0;
}
static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
Link *link;
assert(dhcp6_link);
assert(dhcp6_link->manager);
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
if (link == dhcp6_link)
continue;
if (!link_dhcp6_pd_is_enabled(link))
continue;
return true;
}
return false;
}
static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) {
const DUID *duid;
int r;
@ -1559,11 +1540,10 @@ static int dhcp6_configure(Link *link) {
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set callback: %m");
if (dhcp6_enable_prefix_delegation(link)) {
r = sd_dhcp6_client_set_prefix_delegation(client, true);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set prefix delegation: %m");
}
r = sd_dhcp6_client_set_prefix_delegation(client, link->network->dhcp6_use_pd_prefix);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to %s prefix delegation: %m",
enable_disable(link->network->dhcp6_use_pd_prefix));
if (link->network->dhcp6_pd_prefix_length > 0) {
r = sd_dhcp6_client_set_prefix_delegation_hint(client,

View file

@ -238,6 +238,7 @@ DHCPv4.SendVendorOption, config_parse_dhcp_send_option,
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0
DHCPv6.UseAddress, config_parse_bool, 0, offsetof(Network, dhcp6_use_address)
DHCPv6.UseDelegatedPrefix, config_parse_bool, 0, offsetof(Network, dhcp6_use_pd_prefix)
DHCPv6.UseDNS, config_parse_dhcp_use_dns, AF_INET6, 0
DHCPv6.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp6_use_hostname)
DHCPv6.UseDomains, config_parse_dhcp_use_domains, AF_INET6, 0

View file

@ -400,6 +400,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_broadcast = -1,
.dhcp6_use_address = true,
.dhcp6_use_pd_prefix = true,
.dhcp6_use_dns = true,
.dhcp6_use_hostname = true,
.dhcp6_use_ntp = true,

View file

@ -169,6 +169,7 @@ struct Network {
/* DHCPv6 Client support */
bool dhcp6_use_address;
bool dhcp6_use_pd_prefix;
bool dhcp6_use_dns;
bool dhcp6_use_dns_set;
bool dhcp6_use_hostname;

View file

@ -130,6 +130,7 @@ RouteMTUBytes=
FallbackLeaseLifetimeSec=
[DHCPv6]
UseAddress=
UseDelegatedPrefix=
UseNTP=
UseDNS=
UseHostname=