summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-10-23 05:57:58 +0200
committerGitHub <noreply@github.com>2020-10-23 05:57:58 +0200
commit9c914c0401546a67079a22c4a928814bd645b0a5 (patch)
treeb33772ffbba60d3642c595d5514a567a3c100ac7
parentnetwork: move set-MAC and set-nomaster operations out of link_up() (diff)
parenttest-network: use new IPv6SendRA= setting (diff)
downloadsystemd-9c914c0401546a67079a22c4a928814bd645b0a5.tar.xz
systemd-9c914c0401546a67079a22c4a928814bd645b0a5.zip
Merge pull request #17357 from yuwata/network-dhcp6-pd-announce-17353
network: add an option to control announcement of delegated prefix
-rw-r--r--man/systemd.network.xml78
-rw-r--r--src/network/networkd-address.c39
-rw-r--r--src/network/networkd-dhcp4.c4
-rw-r--r--src/network/networkd-dhcp6.c13
-rw-r--r--src/network/networkd-network-gperf.gperf38
-rw-r--r--src/network/networkd-network.c48
-rw-r--r--src/network/networkd-network.h89
-rw-r--r--src/network/networkd-radv.c133
-rw-r--r--src/network/networkd-radv.h1
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network15
-rw-r--r--test/test-network/conf/ipv6-prefix.network4
-rw-r--r--test/test-network/conf/ipv6ra-prefix.network2
12 files changed, 294 insertions, 170 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 5307a508d3..1eb8274e83 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -810,18 +810,24 @@ 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).
An integer greater than or equal to 1280 bytes. When unset, the kernel's default will be used.
@@ -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>
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 636812b556..9130fae778 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -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) {
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index a881df8bb4..bb8c34f7cc 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -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");
}
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 5217497f98..d9cc4ccf41 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -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");
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 21d2e820e9..5cc9e3e8f6 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -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)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 6bfc4cb9eb..426dd0a8f0 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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();
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index ccf739c851..92c7a4636f 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -57,12 +57,14 @@ typedef struct NetworkDHCPServerEmitAddress {
struct Network {
Manager *manager;
- char *filename;
+ unsigned n_ref;
+
char *name;
+ char *filename;
usec_t timestamp;
+ char *description;
- unsigned n_ref;
-
+ /* [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);
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index bb80e91b6c..eb10f21cbd 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -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,
diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h
index fbb93a9acc..75c606d15e 100644
--- a/src/network/networkd-radv.h
+++ b/src/network/networkd-radv.h
@@ -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);
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 1494daa0c1..cb0c3205a0 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -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=
diff --git a/test/test-network/conf/ipv6-prefix.network b/test/test-network/conf/ipv6-prefix.network
index 9de0e3147b..aec1d1b2c3 100644
--- a/test/test-network/conf/ipv6-prefix.network
+++ b/test/test-network/conf/ipv6-prefix.network
@@ -2,9 +2,9 @@
Name=veth-peer
[Network]
-IPv6PrefixDelegation=yes
+IPv6SendRA=yes
-[IPv6PrefixDelegation]
+[IPv6SendRA]
DNS=_link_local 2002:da8:1:0::1
DNSLifetimeSec=1min
diff --git a/test/test-network/conf/ipv6ra-prefix.network b/test/test-network/conf/ipv6ra-prefix.network
index 9dc32cb4da..a0ac1e4537 100644
--- a/test/test-network/conf/ipv6ra-prefix.network
+++ b/test/test-network/conf/ipv6ra-prefix.network
@@ -3,7 +3,7 @@ Name=veth99
[Network]
DHCP=no
-IPv6PrefixDelegation=yes
+IPv6SendRA=yes
[IPv6Prefix]
Prefix=2001:db8:0:1::/64