Merge pull request #17357 from yuwata/network-dhcp6-pd-announce-17353

network: add an option to control announcement of delegated prefix
This commit is contained in:
Yu Watanabe 2020-10-23 12:57:58 +09:00 committed by GitHub
commit 9c914c0401
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 295 additions and 171 deletions

View file

@ -810,17 +810,23 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>IPv6PrefixDelegation=</varname></term>
<listitem><para>Whether to enable or disable Router Advertisement sending on a link. Allowed
values are <literal>static</literal> which distributes prefixes as defined in the
[IPv6PrefixDelegation] and any [IPv6Prefix] sections, <literal>dhcpv6</literal> which requests
prefixes using a DHCPv6 client configured for another link and any values configured in the
[IPv6PrefixDelegation] section while ignoring all static prefix configuration sections,
<literal>yes</literal> which uses both static configuration and DHCPv6, and
<literal>false</literal> which turns off IPv6 prefix delegation altogether. Defaults to
<literal>false</literal>. See the [IPv6PrefixDelegation] and the [IPv6Prefix] sections for more
<term><varname>IPv6SendRA=</varname></term>
<listitem><para>Whether to enable or disable Router Advertisement sending on a link. Takes a
boolean value. When enabled, prefixes configured in [IPv6Prefix] sections and routes
configured in [IPv6RoutePrefix] sections are distributed as defined in the [IPv6SendRA]
section. If <varname>DHCPv6PrefixDelegation=</varname> is enabled, then the delegated
prefixes are also distributed. See <varname>DHCPv6PrefixDelegation=</varname> setting and the
[IPv6SendRA], [IPv6Prefix], [IPv6RoutePrefix], and [DHCPv6PrefixDelegation] sections for more
configuration options.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>DHCPv6PrefixDelegation=</varname></term>
<listitem><para>Takes a boolean value. When enabled, requests prefixes using a DHCPv6 client
configured on another link. By default, an address within each delegated prefix will be
assigned, and the prefixes will be announced through IPv6 Router Advertisement when
<varname>IPv6SendRA=</varname> is enabled. Such default settings can be configured in
[DHCPv6PrefixDelegation] section.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>IPv6MTUBytes=</varname></term>
<listitem><para>Configures IPv6 maximum transmission unit (MTU).
@ -1957,9 +1963,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<refsect1>
<title>[DHCPv6PrefixDelegation] Section Options</title>
<para>The [DHCPv6PrefixDelegation] section configures delegated prefix assigned by DHCPv6 server.
The settings in this section are used only when <varname>IPv6PrefixDelegation=</varname> setting is
enabled, or set to <literal>dhcpv6</literal>.</para>
<para>The [DHCPv6PrefixDelegation] section configures delegated prefixes assigned by DHCPv6 server.
The settings in this section are used only when <varname>DHCPv6PrefixDelegation=</varname> setting
is enabled.</para>
<variablelist class='network-directives'>
<varlistentry>
@ -1969,9 +1975,16 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
delegation. You can either set "auto" (the default) or a specific subnet ID (as defined in
<ulink url="https://tools.ietf.org/html/rfc4291#section-2.5.4">RFC 4291</ulink>, section
2.5.4), in which case the allowed value is hexadecimal, from 0 to 0x7fffffffffffffff
inclusive. This option is only effective when used together with
<varname>IPv6PrefixDelegation=</varname> and the corresponding configuration on the upstream
interface.</para>
inclusive.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Announce=</varname></term>
<listitem>
<para>Takes a boolean. When enabled, and <varname>IPv6SendRA=</varname> in [Network] section
is enabled, the delegated prefixes are distributed through the IPv6 Router Advertisement.
Defaults to yes.</para>
</listitem>
</varlistentry>
@ -1979,19 +1992,22 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<term><varname>Assign=</varname></term>
<listitem>
<para>Takes a boolean. Specifies whether to add an address from the delegated prefixes which
are received from the WAN interface by the <varname>IPv6PrefixDelegation=</varname>. When
true (on LAN interfce), the EUI-64 algorithm will be used to form an interface identifier
from the delegated prefixes. Defaults to true.</para>
are received from the WAN interface by the DHCPv6 Prefix Delegation. When true (on LAN
interfce), the EUI-64 algorithm will be used by default to form an interface identifier from
the delegated prefixes. See also <varname>Token=</varname> setting below. Defaults to yes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Token=</varname></term>
<listitem>
<para>Specifies an optional address generation mode for <varname>Assign=</varname>. Takes an
IPv6 address. When set, the lower bits of the supplied address are combined with the upper
bits of a delegatad prefix received from the WAN interface by the
<varname>IPv6PrefixDelegation=</varname> prefixes to form a complete address.</para>
<para>Specifies an optional address generation mode for assigning an address in each
delegated prefix. Takes an IPv6 address. When set, the lower bits of the supplied address is
combined with the upper bits of each delegatad prefix received from the WAN interface by the
DHCPv6 Prefix Delegation to form a complete address. When <varname>Assign=</varname> is
disabled, this setting is ignored. When unset, the EUI-64 algorithm will be used to form
addresses. Defaults to unset.</para>
</listitem>
</varlistentry>
</variablelist>
@ -2213,10 +2229,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</refsect1>
<refsect1>
<title>[IPv6PrefixDelegation] Section Options</title>
<para>The [IPv6PrefixDelegation] section contains settings for sending IPv6 Router Advertisements and
whether to act as a router, if enabled via the <varname>IPv6PrefixDelegation=</varname> option described
above. IPv6 network prefixes are defined with one or more [IPv6Prefix] sections.</para>
<title>[IPv6SendRA] Section Options</title>
<para>The [IPv6SendRA] section contains settings for sending IPv6 Router Advertisements and whether
to act as a router, if enabled via the <varname>IPv6SendRA=</varname> option described above. IPv6
network prefixes or routes are defined with one or more [IPv6Prefix] or [IPv6RoutePrefix] sections.
</para>
<variablelist class='network-directives'>
@ -3586,10 +3603,13 @@ DHCP=ipv6</programlisting>
Name=enp2s0
[Network]
IPv6PrefixDelegation=dhcpv6</programlisting>
IPv6SendRA=yes
DHCPv6PrefixDelegation=yes</programlisting>
<para>This will enable IPv6 PD on the interface enp1s0 as an upstream interface where the
DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.</para>
<para>This will enable DHCPv6-PD on the interface enp1s0 as an upstream interface where the
DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.
The delegated prefixes are distributed by IPv6 Router Advertisement on the downstream network.
</para>
</example>
<example>

View file

@ -980,6 +980,7 @@ static int static_address_configure(const Address *address, Link *link, bool upd
int link_set_addresses(Link *link) {
Address *ad;
Prefix *p;
int r;
assert(link);
@ -1000,32 +1001,28 @@ int link_set_addresses(Link *link) {
return r;
}
if (link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_STATIC) {
Prefix *p;
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
_cleanup_(address_freep) Address *address = NULL;
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
_cleanup_(address_freep) Address *address = NULL;
if (!p->assign)
continue;
if (!p->assign)
continue;
r = address_new(&address);
if (r < 0)
return log_oom();
r = address_new(&address);
if (r < 0)
return log_oom();
r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
if (r < 0)
return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
if (r < 0)
return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
if (r < 0)
return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
if (r < 0)
return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
address->family = AF_INET6;
r = static_address_configure(address, link, true);
if (r < 0)
return r;
}
address->family = AF_INET6;
r = static_address_configure(address, link, true);
if (r < 0)
return r;
}
if (link->address_messages == 0) {

View file

@ -1457,8 +1457,8 @@ int dhcp4_configure(Link *link) {
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
}
if (link->network->ip_service_type > 0) {
r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->ip_service_type);
if (link->network->dhcp_ip_service_type > 0) {
r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type);
if (r < 0)
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m");
}

View file

@ -31,7 +31,7 @@ bool link_dhcp6_pd_is_enabled(Link *link) {
if (!link->network)
return false;
return link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_DHCP6;
return link->network->dhcp6_pd;
}
static bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) {
@ -421,11 +421,14 @@ static int dhcp6_pd_assign_prefix(Link *link, const union in_addr_union *prefix,
int r;
assert(link);
assert(link->network);
assert(prefix);
r = radv_add_prefix(link, &prefix->in6, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
if (link->network->dhcp6_pd_announce) {
r = radv_add_prefix(link, &prefix->in6, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
}
r = dhcp6_set_pd_route(link, prefix, pd_prefix);
if (r < 0)
@ -1424,7 +1427,7 @@ int dhcp6_configure(Link *link) {
if (r < 0)
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set ifindex: %m");
if (link->network->rapid_commit) {
if (link->network->dhcp6_rapid_commit) {
r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_RAPID_COMMIT);
if (r < 0)
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for rapid commit: %m");

View file

@ -126,6 +126,8 @@ Network.BindCarrier, config_parse_strv,
Network.ConfigureWithoutCarrier, config_parse_bool, 0, offsetof(Network, configure_without_carrier)
Network.IgnoreCarrierLoss, config_parse_tristate, 0, offsetof(Network, ignore_carrier_loss)
Network.KeepConfiguration, config_parse_keep_configuration, 0, offsetof(Network, keep_configuration)
Network.IPv6SendRA, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
Network.DHCPv6PrefixDelegation, config_parse_tristate, 0, offsetof(Network, dhcp6_pd)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0
Address.Broadcast, config_parse_broadcast, 0, 0
@ -209,14 +211,14 @@ DHCPv4.SendRelease, config_parse_bool,
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
DHCPv4.DenyList, config_parse_dhcp_acl_ip_address, 0, 0
DHCPv4.AllowList, config_parse_dhcp_acl_ip_address, 0, 0
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, ip_service_type)
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, dhcp_ip_service_type)
DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options)
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0
DHCPv6.UseDNS, config_parse_dhcp_use_dns, 0, 0
DHCPv6.UseNTP, config_parse_dhcp_use_ntp, 0, 0
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit)
DHCPv6.MUDURL, config_parse_dhcp6_mud_url, 0, 0
DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0
DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class)
@ -280,19 +282,19 @@ BridgeMDB.VLANId, config_parse_mdb_vlan_id,
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
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.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token)
IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
IPv6PrefixDelegation.RouterPreference, config_parse_router_preference, 0, 0
IPv6PrefixDelegation.EmitDNS, config_parse_bool, 0, offsetof(Network, router_emit_dns)
IPv6PrefixDelegation.DNS, config_parse_radv_dns, 0, 0
IPv6PrefixDelegation.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains)
IPv6PrefixDelegation.Domains, config_parse_radv_search_domains, 0, 0
IPv6PrefixDelegation.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
IPv6SendRA.RouterPreference, config_parse_router_preference, 0, 0
IPv6SendRA.EmitDNS, config_parse_bool, 0, offsetof(Network, router_emit_dns)
IPv6SendRA.DNS, config_parse_radv_dns, 0, 0
IPv6SendRA.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains)
IPv6SendRA.Domains, config_parse_radv_search_domains, 0, 0
IPv6SendRA.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
IPv6Prefix.Prefix, config_parse_prefix, 0, 0
IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
@ -429,6 +431,16 @@ TrivialLinkEqualizer.Handle, config_parse_qdisc_handle,
TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer_id, QDISC_KIND_TEQL, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
IPv6PrefixDelegation.RouterPreference, config_parse_router_preference, 0, 0
IPv6PrefixDelegation.EmitDNS, config_parse_bool, 0, offsetof(Network, router_emit_dns)
IPv6PrefixDelegation.DNS, config_parse_radv_dns, 0, 0
IPv6PrefixDelegation.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains)
IPv6PrefixDelegation.Domains, config_parse_radv_search_domains, 0, 0
IPv6PrefixDelegation.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
DHCPv4.BlackList, config_parse_dhcp_acl_ip_address, 0, 0
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_dhcp_use_dns, 0, 0
@ -452,7 +464,7 @@ DHCP.RouteTable, config_parse_section_route_table,
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.IAID, config_parse_iaid, 0, 0
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit)
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)

View file

@ -214,14 +214,6 @@ int network_verify(Network *network) {
if (network->link_local < 0)
network->link_local = network->bridge ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_IPV6;
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE) {
log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
"Disabling IPv6PrefixDelegation=.", network->filename);
network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
}
}
if (FLAGS_SET(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4) &&
!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4)) {
log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
@ -235,6 +227,7 @@ int network_verify(Network *network) {
network_adjust_ipv6_accept_ra(network);
network_adjust_dhcp(network);
network_adjust_radv(network);
if (network->mtu > 0 && network->dhcp_use_mtu) {
log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
@ -336,7 +329,16 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.required_for_online = true,
.required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT,
.arp = -1,
.multicast = -1,
.allmulticast = -1,
.configure_without_carrier = false,
.ignore_carrier_loss = -1,
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
.dhcp = ADDRESS_FAMILY_NO,
.duid.type = _DUID_TYPE_INVALID,
.dhcp_critical = -1,
.dhcp_use_ntp = true,
.dhcp_use_sip = true,
@ -358,14 +360,17 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_use_mtu = false,
/* NOTE: from man: UseTimezone=... Defaults to "no".*/
.dhcp_use_timezone = false,
.rapid_commit = true,
.dhcp_ip_service_type = -1,
.dhcp6_rapid_commit = true,
.dhcp6_route_metric = DHCP_ROUTE_METRIC,
.dhcp6_use_ntp = true,
.dhcp6_use_dns = true,
.dhcp6_pd_subnet_id = -1,
.dhcp6_pd = -1,
.dhcp6_pd_announce = true,
.dhcp6_pd_assign = true,
.dhcp6_pd_subnet_id = -1,
.dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true,
.dhcp_server_emit[SD_DHCP_LEASE_NTP].emit = true,
@ -404,17 +409,13 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
.ipv4_accept_local = -1,
.ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
.ipv6_accept_ra = -1,
.ipv6_dad_transmits = -1,
.ipv6_hop_limit = -1,
.ipv6_proxy_ndp = -1,
.duid.type = _DUID_TYPE_INVALID,
.proxy_arp = -1,
.arp = -1,
.multicast = -1,
.allmulticast = -1,
.ipv6_accept_ra_use_dns = true,
.ipv6_accept_ra_use_autonomous_prefix = true,
.ipv6_accept_ra_use_onlink_prefix = true,
@ -422,15 +423,11 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_route_table_set = false,
.ipv6_accept_ra_start_dhcp6_client = true,
.configure_without_carrier = false,
.ignore_carrier_loss = -1,
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
.can_triple_sampling = -1,
.can_termination = -1,
.can_listen_only = -1,
.can_fd_mode = -1,
.can_non_iso = -1,
.ip_service_type = -1,
};
r = config_parse_many(
@ -456,6 +453,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"BridgeFDB\0"
"BridgeMDB\0"
"BridgeVLAN\0"
"IPv6SendRA\0"
"IPv6PrefixDelegation\0"
"IPv6Prefix\0"
"IPv6RoutePrefix\0"
@ -620,11 +618,11 @@ static Network *network_free(Network *network) {
for (unsigned i = 0; i < network->n_dns; i++)
in_addr_full_free(network->dns[i]);
free(network->dns);
ordered_set_free_free(network->search_domains);
ordered_set_free_free(network->route_domains);
ordered_set_free(network->search_domains);
ordered_set_free(network->route_domains);
strv_free(network->bind_carrier);
ordered_set_free_free(network->router_search_domains);
ordered_set_free(network->router_search_domains);
free(network->router_dns);
set_free_free(network->ndisc_deny_listed_prefix);
@ -864,8 +862,8 @@ int config_parse_domains(
assert(rvalue);
if (isempty(rvalue)) {
n->search_domains = ordered_set_free_free(n->search_domains);
n->route_domains = ordered_set_free_free(n->route_domains);
n->search_domains = ordered_set_free(n->search_domains);
n->route_domains = ordered_set_free(n->route_domains);
return 0;
}
@ -913,7 +911,7 @@ int config_parse_domains(
}
OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
r = ordered_set_ensure_allocated(set, &string_hash_ops);
r = ordered_set_ensure_allocated(set, &string_hash_ops_free);
if (r < 0)
return log_oom();

View file

@ -57,12 +57,14 @@ typedef struct NetworkDHCPServerEmitAddress {
struct Network {
Manager *manager;
char *filename;
char *name;
usec_t timestamp;
unsigned n_ref;
char *name;
char *filename;
usec_t timestamp;
char *description;
/* [Match] section */
Set *match_mac;
Set *match_permanent_mac;
char **match_path;
@ -75,8 +77,7 @@ struct Network {
Set *match_bssid;
LIST_HEAD(Condition, conditions);
char *description;
/* Master or stacked netdevs */
NetDev *bridge;
NetDev *bond;
NetDev *vrf;
@ -87,9 +88,31 @@ struct Network {
char *vrf_name;
Hashmap *stacked_netdev_names;
/* [Link] section */
struct ether_addr *mac;
uint32_t mtu;
uint32_t group;
int arp;
int multicast;
int allmulticast;
bool unmanaged;
bool required_for_online; /* Is this network required to be considered online? */
LinkOperationalStateRange required_operstate_for_online;
/* misc settings */
bool configure_without_carrier;
int ignore_carrier_loss;
KeepConfiguration keep_configuration;
char **bind_carrier;
bool default_route_on_device;
bool ip_masquerade;
/* DHCP Client Support */
AddressFamily dhcp;
DHCPClientIdentifier dhcp_client_identifier;
DUID duid;
uint32_t iaid;
bool iaid_set;
char *dhcp_vendor_class_identifier;
char *dhcp_mudurl;
char **dhcp_user_class;
@ -102,7 +125,7 @@ struct Network {
uint32_t dhcp_route_mtu;
uint16_t dhcp_client_port;
int dhcp_critical;
int ip_service_type;
int dhcp_ip_service_type;
bool dhcp_anonymize;
bool dhcp_send_hostname;
bool dhcp_broadcast;
@ -116,7 +139,6 @@ struct Network {
bool dhcp_use_routes;
int dhcp_use_gateway;
bool dhcp_use_timezone;
bool rapid_commit;
bool dhcp_use_hostname;
bool dhcp_route_table_set;
bool dhcp_send_release;
@ -127,14 +149,13 @@ struct Network {
Set *dhcp_request_options;
OrderedHashmap *dhcp_client_send_options;
OrderedHashmap *dhcp_client_send_vendor_options;
OrderedHashmap *dhcp_server_send_options;
OrderedHashmap *dhcp_server_send_vendor_options;
/* DHCPv6 Client support*/
bool dhcp6_use_dns;
bool dhcp6_use_dns_set;
bool dhcp6_use_ntp;
bool dhcp6_use_ntp_set;
bool dhcp6_rapid_commit;
uint8_t dhcp6_pd_length;
uint32_t dhcp6_route_metric;
bool dhcp6_route_metric_set;
@ -146,6 +167,8 @@ struct Network {
OrderedHashmap *dhcp6_client_send_options;
OrderedHashmap *dhcp6_client_send_vendor_options;
Set *dhcp6_request_options;
/* Start DHCPv6 PD also when 'O' RA flag is set, see RFC 7084, WPD-4 */
bool dhcp6_force_pd_other_information;
/* DHCP Server Support */
bool dhcp_server;
@ -156,15 +179,15 @@ struct Network {
usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec;
uint32_t dhcp_server_pool_offset;
uint32_t dhcp_server_pool_size;
OrderedHashmap *dhcp_server_send_options;
OrderedHashmap *dhcp_server_send_vendor_options;
/* link local addressing support */
AddressFamily link_local;
IPv6LinkLocalAddressGenMode ipv6ll_address_gen_mode;
bool ipv4ll_route;
bool default_route_on_device;
/* IPv6 prefix delegation support */
/* IPv6 RA support */
RADVPrefixDelegation router_prefix_delegation;
usec_t router_lifetime_usec;
uint8_t router_preference;
@ -176,13 +199,12 @@ struct Network {
struct in6_addr *router_dns;
unsigned n_router_dns;
OrderedSet *router_search_domains;
bool dhcp6_force_pd_other_information; /* Start DHCPv6 PD also when 'O'
RA flag is set, see RFC 7084,
WPD-4 */
/* DHCPv6 Prefix Delegation support */
int64_t dhcp6_pd_subnet_id;
int dhcp6_pd;
bool dhcp6_pd_announce;
bool dhcp6_pd_assign;
int64_t dhcp6_pd_subnet_id;
union in_addr_union dhcp6_pd_token;
/* Bridge Support */
@ -201,6 +223,7 @@ struct Network {
uint16_t priority;
MulticastRouter multicast_router;
/* Bridge VLAN */
bool use_br_vlan;
uint16_t pvid;
uint32_t br_vid_bitmap[BRIDGE_VLAN_BITMAP_LEN];
@ -218,18 +241,19 @@ struct Network {
int can_fd_mode;
int can_non_iso;
/* sysctl settings */
AddressFamily ip_forward;
bool ip_masquerade;
int ipv4_accept_local;
int ipv6_accept_ra;
int ipv6_dad_transmits;
int ipv6_hop_limit;
int ipv6_proxy_ndp;
Set *ipv6_proxy_ndp_addresses;
int proxy_arp;
uint32_t ipv6_mtu;
IPv6PrivacyExtensions ipv6_privacy_extensions;
int ipv6_proxy_ndp;
Set *ipv6_proxy_ndp_addresses;
/* IPv6 accept RA */
int ipv6_accept_ra;
bool ipv6_accept_ra_use_dns;
bool ipv6_accept_ra_use_autonomous_prefix;
bool ipv6_accept_ra_use_onlink_prefix;
@ -242,26 +266,6 @@ struct Network {
Set *ndisc_deny_listed_prefix;
OrderedSet *ipv6_tokens;
IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac;
uint32_t mtu;
uint32_t group;
int arp;
int multicast;
int allmulticast;
bool unmanaged;
bool configure_without_carrier;
int ignore_carrier_loss;
KeepConfiguration keep_configuration;
uint32_t iaid;
DUID duid;
bool iaid_set;
bool required_for_online; /* Is this network required to be considered online? */
LinkOperationalStateRange required_operstate_for_online;
/* LLDP support */
LLDPMode lldp_mode; /* LLDP reception */
LLDPEmit lldp_emit; /* LLDP transmission */
@ -284,7 +288,6 @@ struct Network {
struct in_addr_full **dns;
unsigned n_dns;
OrderedSet *search_domains, *route_domains;
int dns_default_route;
ResolveSupport llmnr;
ResolveSupport mdns;
@ -292,8 +295,8 @@ struct Network {
DnsOverTlsMode dns_over_tls_mode;
Set *dnssec_negative_trust_anchors;
/* NTP */
char **ntp;
char **bind_carrier;
};
Network *network_ref(Network *network);

View file

@ -180,6 +180,35 @@ void network_drop_invalid_route_prefixes(Network *network) {
route_prefix_free(prefix);
}
void network_adjust_radv(Network *network) {
assert(network);
/* After this function is called, network->router_prefix_delegation can be treated as a boolean. */
if (network->dhcp6_pd < 0)
/* For backward compatibility. */
network->dhcp6_pd = FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6);
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE)
log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
"Disabling IPv6PrefixDelegation=.", network->filename);
network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
}
if (network->router_prefix_delegation == RADV_PREFIX_DELEGATION_NONE) {
network->n_router_dns = 0;
network->router_dns = mfree(network->router_dns);
network->router_search_domains = ordered_set_free(network->router_search_domains);
}
if (!FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_STATIC)) {
network->prefixes_by_section = hashmap_free_with_destructor(network->prefixes_by_section, prefix_free);
network->route_prefixes_by_section = hashmap_free_with_destructor(network->route_prefixes_by_section, route_prefix_free);
}
}
int config_parse_prefix(
const char *unit,
const char *filename,
@ -608,10 +637,12 @@ static bool link_radv_enabled(Link *link) {
if (!link_ipv6ll_enabled(link))
return false;
return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE;
return link->network->router_prefix_delegation;
}
int radv_configure(Link *link) {
RoutePrefix *q;
Prefix *p;
int r;
assert(link);
@ -658,29 +689,24 @@ int radv_configure(Link *link) {
return r;
}
if (link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_STATIC) {
RoutePrefix *q;
Prefix *p;
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
if (r == -EEXIST)
continue;
if (r == -ENOEXEC) {
log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
continue;
}
if (r < 0)
return r;
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
if (r == -EEXIST)
continue;
if (r == -ENOEXEC) {
log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
continue;
}
if (r < 0)
return r;
}
HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
if (r == -EEXIST)
continue;
if (r < 0)
return r;
}
HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
if (r == -EEXIST)
continue;
if (r < 0)
return r;
}
return 0;
@ -771,6 +797,12 @@ int config_parse_radv_dns(
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
n->n_router_dns = 0;
n->router_dns = mfree(n->router_dns);
return 0;
}
for (const char *p = rvalue;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
@ -832,6 +864,11 @@ int config_parse_radv_search_domains(
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
n->router_search_domains = ordered_set_free(n->router_search_domains);
return 0;
}
for (const char *p = rvalue;;) {
_cleanup_free_ char *w = NULL, *idna = NULL;
@ -855,7 +892,7 @@ int config_parse_radv_search_domains(
/* transfer ownership to simplify subsequent operations */
idna = TAKE_PTR(w);
r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops);
r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops_free);
if (r < 0)
return log_oom();
@ -877,11 +914,51 @@ DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(
RADVPrefixDelegation,
RADV_PREFIX_DELEGATION_BOTH);
DEFINE_CONFIG_PARSE_ENUM(
config_parse_router_prefix_delegation,
radv_prefix_delegation,
RADVPrefixDelegation,
"Invalid router prefix delegation");
int config_parse_router_prefix_delegation(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
RADVPrefixDelegation val, *ra = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (streq(lvalue, "IPv6SendRA")) {
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid %s= setting, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
/* When IPv6SendRA= is enabled, only static prefixes are sent by default, and users
* need to explicitly enable DHCPv6PrefixDelegation=. */
*ra = r ? RADV_PREFIX_DELEGATION_STATIC : RADV_PREFIX_DELEGATION_NONE;
return 0;
}
/* For backward compatibility */
val = radv_prefix_delegation_from_string(rvalue);
if (val < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= setting, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
*ra = val;
return 0;
}
int config_parse_router_preference(
const char *unit,

View file

@ -47,6 +47,7 @@ RoutePrefix *route_prefix_free(RoutePrefix *prefix);
void network_drop_invalid_prefixes(Network *network);
void network_drop_invalid_route_prefixes(Network *network);
void network_adjust_radv(Network *network);
int radv_emit_dns(Link *link);
int radv_configure(Link *link);

View file

@ -137,6 +137,7 @@ SendVendorOption=
RouteMetric=
[DHCPv6PrefixDelegation]
SubnetId=
Announce=
Assign=
Token=
[Route]
@ -190,6 +191,7 @@ DNSOverTLS=
Bond=
IPv6ProxyNDP=
DNS=
DNSDefaultRoute=
ActiveSlave=
LLMNR=
DNSSEC=
@ -207,6 +209,7 @@ ConfigureWithoutCarrier=
NTP=
DHCP=
Domains=
IPv6SendRA=
IPv6PrefixDelegation=
VLAN=
DHCPServer=
@ -214,6 +217,7 @@ BindCarrier=
VRF=
IgnoreCarrierLoss=
KeepConfiguration=
DHCPv6PrefixDelegation=
[IPv6Prefix]
Prefix=
OnLink=
@ -270,11 +274,20 @@ InvertRule=
Family=
SuppressPrefixLength=
User=
[IPv6SendRA]
RouterPreference=
DNSLifetimeSec=
DNS=
RouterLifetimeSec=
Domains=
EmitDNS=
EmitDomains=
Managed=
OtherInformation=
[IPv6PrefixDelegation]
RouterPreference=
DNSLifetimeSec=
DNS=
DNSDefaultRoute=
RouterLifetimeSec=
Domains=
EmitDNS=

View file

@ -2,9 +2,9 @@
Name=veth-peer
[Network]
IPv6PrefixDelegation=yes
IPv6SendRA=yes
[IPv6PrefixDelegation]
[IPv6SendRA]
DNS=_link_local 2002:da8:1:0::1
DNSLifetimeSec=1min

View file

@ -3,7 +3,7 @@ Name=veth99
[Network]
DHCP=no
IPv6PrefixDelegation=yes
IPv6SendRA=yes
[IPv6Prefix]
Prefix=2001:db8:0:1::/64