summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml43
-rw-r--r--src/network/networkd-dhcp-common.c66
-rw-r--r--src/network/networkd-dhcp-common.h2
-rw-r--r--src/network/networkd-link.c4
-rw-r--r--src/network/networkd-network-gperf.gperf84
-rw-r--r--src/network/networkd-network.c4
-rw-r--r--src/network/networkd-network.h4
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network39
-rw-r--r--test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network11
-rw-r--r--test/test-network/conf/dhcp-client-use-dns-ipv4.network14
-rw-r--r--test/test-network/conf/dhcp-client-use-dns-no.network11
-rw-r--r--test/test-network/conf/dhcp-client-use-dns-yes.network11
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py132
13 files changed, 370 insertions, 55 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index c48b294551..c544315601 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -324,8 +324,8 @@
specified through DHCP is not used for name resolution.
See option <option>UseDomains=</option> below.</para>
- <para>See the <literal>[DHCP]</literal> section below for further configuration options for the DHCP client
- support.</para>
+ <para>See the <literal>[DHCPv4]</literal> or <literal>[DHCPv6]</literal> section below for
+ further configuration options for the DHCP client support.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1299,9 +1299,9 @@
</refsect1>
<refsect1>
- <title>[DHCP] Section Options</title>
- <para>The <literal>[DHCP]</literal> section configures the
- DHCPv4 and DHCP6 client, if it is enabled with the
+ <title>[DHCPv4] Section Options</title>
+ <para>The <literal>[DHCPv4]</literal> section configures the
+ DHCPv4 client, if it is enabled with the
<varname>DHCP=</varname> setting described above:</para>
<variablelist class='network-directives'>
@@ -1535,6 +1535,30 @@
</varlistentry>
<varlistentry>
+ <term><varname>BlackList=</varname></term>
+ <listitem>
+ <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>[DHCPv6] Section Options</title>
+ <para>The <literal>[DHCPv6]</literal> section configures the DHCPv6 client, if it is enabled with the
+ <varname>DHCP=</varname> setting described above, or invoked by the IPv6 Router Advertisement:</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>UseDNS=</varname></term>
+ <term><varname>UseNTP=</varname></term>
+ <listitem>
+ <para>As in the <literal>[DHCP]</literal> section.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>RapidCommit=</varname></term>
<listitem>
<para>Takes a boolean. The DHCPv6 client can obtain configuration parameters from a DHCPv6 server through
@@ -1563,15 +1587,8 @@
</listitem>
</varlistentry>
- <varlistentry>
- <term><varname>BlackList=</varname></term>
- <listitem>
- <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected.</para>
- </listitem>
- </varlistentry>
-
</variablelist>
- </refsect1>
+ </refsect1>
<refsect1>
<title>[IPv6AcceptRA] Section Options</title>
diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c
index 743f2d8ec2..81edb8c7aa 100644
--- a/src/network/networkd-dhcp-common.c
+++ b/src/network/networkd-dhcp-common.c
@@ -57,6 +57,72 @@ int config_parse_dhcp(
return 0;
}
+int config_parse_dhcp_use_dns(
+ 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) {
+
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse UseDNS=%s, ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ network->dhcp_use_dns = r;
+ network->dhcp6_use_dns = r;
+
+ return 0;
+}
+
+int config_parse_dhcp_use_ntp(
+ 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) {
+
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse UseNTP=%s, ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ network->dhcp_use_ntp = r;
+ network->dhcp6_use_ntp = r;
+
+ return 0;
+}
+
int config_parse_section_route_table(
const char *unit,
const char *filename,
diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h
index 0e6e051599..c5af0beada 100644
--- a/src/network/networkd-dhcp-common.h
+++ b/src/network/networkd-dhcp-common.h
@@ -28,6 +28,8 @@ const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index d206589bc4..59f3f1dd31 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -3474,7 +3474,7 @@ int link_save(Link *link) {
space = true;
}
- if (link->network->dhcp_use_dns && dhcp6_lease) {
+ if (link->network->dhcp6_use_dns && dhcp6_lease) {
struct in6_addr *in6_addrs;
r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
@@ -3517,7 +3517,7 @@ int link_save(Link *link) {
space = true;
}
- if (link->network->dhcp_use_ntp && dhcp6_lease) {
+ if (link->network->dhcp6_use_ntp && dhcp6_lease) {
struct in6_addr *in6_addrs;
char **hosts;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 5a2f3f4ea9..ed8c061efb 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -139,32 +139,33 @@ Route.InitialAdvertisedReceiveWindow, config_parse_tcp_window,
Route.QuickAck, config_parse_quickack, 0, 0
Route.FastOpenNoCookie, config_parse_fast_open_no_cookie, 0, 0
Route.TTLPropagate, config_parse_route_ttl_propagate, 0, 0
-DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
-DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
-DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
-DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
-DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
-DHCP.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
-DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_use_routes)
-DHCP.Anonymize, config_parse_bool, 0, offsetof(Network, dhcp_anonymize)
-DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_send_hostname)
-DHCP.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
-DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
-DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) /* deprecated */
-DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
-DHCP.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
-DHCP.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
-DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
-DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
-DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
-DHCP.RouteTable, config_parse_section_route_table, 0, 0
-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.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
-DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
-DHCP.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
-DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
+DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
+DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
+DHCPv4.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
+DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
+DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
+DHCPv4.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
+DHCPv4.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_use_routes)
+DHCPv4.Anonymize, config_parse_bool, 0, offsetof(Network, dhcp_anonymize)
+DHCPv4.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_send_hostname)
+DHCPv4.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
+DHCPv4.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
+DHCPv4.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
+DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
+DHCPv4.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
+DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
+DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
+DHCPv4.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
+DHCPv4.RouteTable, config_parse_section_route_table, 0, 0
+DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
+DHCPv4.IAID, config_parse_iaid, 0, 0
+DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
+DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
+DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
+DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
+DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp)
+DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
+DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
@@ -225,9 +226,32 @@ CAN.RestartSec, config_parse_sec,
CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling)
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
-DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
-DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
-DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
+DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
+DHCP.UseDNS, config_parse_dhcp_use_dns, 0, 0
+DHCP.UseNTP, config_parse_dhcp_use_ntp, 0, 0
+DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
+DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
+DHCP.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
DHCP.UseDomainName, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
+DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_use_routes)
+DHCP.Anonymize, config_parse_bool, 0, offsetof(Network, dhcp_anonymize)
+DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_send_hostname)
+DHCP.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
+DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
+DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
+DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
+DHCP.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
+DHCP.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
+DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
+DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
+DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
+DHCP.RouteTable, config_parse_section_route_table, 0, 0
+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.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
+DHCP.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
+DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, 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_bool, 0, offsetof(Network, dhcp_critical)
+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 3f1753049c..097938057b 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -361,6 +361,9 @@ int network_load_one(Manager *manager, const char *filename) {
.dhcp_use_timezone = false,
.rapid_commit = true,
+ .dhcp6_use_ntp = true,
+ .dhcp6_use_dns = true,
+
.dhcp_server_emit_dns = true,
.dhcp_server_emit_ntp = true,
.dhcp_server_emit_router = true,
@@ -426,6 +429,7 @@ int network_load_one(Manager *manager, const char *filename) {
"Route\0"
"DHCP\0"
"DHCPv4\0" /* compat */
+ "DHCPv6\0"
"DHCPServer\0"
"IPv6AcceptRA\0"
"IPv6NDPProxyAddress\0"
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index a16ec74131..82fad492a8 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -102,6 +102,10 @@ struct Network {
DHCPUseDomains dhcp_use_domains;
Set *dhcp_black_listed_ip;
+ /* DHCPv6 Client support*/
+ bool dhcp6_use_dns;
+ bool dhcp6_use_ntp;
+
/* DHCP Server Support */
bool dhcp_server;
bool dhcp_server_emit_dns;
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index ddafaa7840..b895e09d53 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -66,6 +66,38 @@ UseTimezone=
RouteTable=
BlackList=
SendRelease=
+MaxAttempts=
+[DHCPv4]
+UseDNS=
+UseDomains=
+UseRoutes=
+IAID=
+UserClass=
+UseNTP=
+UseMTU=
+UseDomainName=
+RouteMetric=
+SendHostname=
+Anonymize=
+VendorClassIdentifier=
+Hostname=
+DUIDType=
+UseHostname=
+CriticalConnection=
+DUIDRawData=
+RequestBroadcast=
+ClientIdentifier=
+ListenPort=
+UseTimezone=
+RouteTable=
+BlackList=
+SendRelease=
+MaxAttempts=
+[DHCPv6]
+UseNTP=
+UseDNS=
+RapidCommit=
+ForceDHCPv6PDOtherInformation=
[Route]
Destination=
Protocol=
@@ -214,10 +246,3 @@ MaxLeaseTimeSec=
DefaultLeaseTimeSec=
EmitTimezone=
DNS=
-MaxAttempts=
-[DHCPv4]
-UseHostname=
-UseMTU=
-UseDomainName=
-CriticalConnection=
-UseDNS=
diff --git a/test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network b/test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network
new file mode 100644
index 0000000000..ed5989555c
--- /dev/null
+++ b/test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network
@@ -0,0 +1,11 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+
+[DHCP]
+UseDNS=yes
+
+[IPv6AcceptRA]
+UseDNS=yes
diff --git a/test/test-network/conf/dhcp-client-use-dns-ipv4.network b/test/test-network/conf/dhcp-client-use-dns-ipv4.network
new file mode 100644
index 0000000000..dbd0f7f3fe
--- /dev/null
+++ b/test/test-network/conf/dhcp-client-use-dns-ipv4.network
@@ -0,0 +1,14 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+
+[DHCPv4]
+UseDNS=yes
+
+[DHCPv6]
+UseDNS=no
+
+[IPv6AcceptRA]
+UseDNS=no
diff --git a/test/test-network/conf/dhcp-client-use-dns-no.network b/test/test-network/conf/dhcp-client-use-dns-no.network
new file mode 100644
index 0000000000..891efdbe12
--- /dev/null
+++ b/test/test-network/conf/dhcp-client-use-dns-no.network
@@ -0,0 +1,11 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=yes
+
+[DHCP]
+UseDNS=no
+
+[IPv6AcceptRA]
+UseDNS=no
diff --git a/test/test-network/conf/dhcp-client-use-dns-yes.network b/test/test-network/conf/dhcp-client-use-dns-yes.network
new file mode 100644
index 0000000000..f38ffe36e3
--- /dev/null
+++ b/test/test-network/conf/dhcp-client-use-dns-yes.network
@@ -0,0 +1,11 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=yes
+
+[DHCP]
+UseDNS=yes
+
+[IPv6AcceptRA]
+UseDNS=no
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index 2139c5f9d3..7e9a4ee0b1 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -23,8 +23,11 @@ dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
networkd_bin='/usr/lib/systemd/systemd-networkd'
+resolved_bin='/usr/lib/systemd/systemd-resolved'
wait_online_bin='/usr/lib/systemd/systemd-networkd-wait-online'
networkctl_bin='/usr/bin/networkctl'
+resolvectl_bin='/usr/bin/resolvectl'
+timedatectl_bin='/usr/bin/timedatectl'
use_valgrind=False
enable_debug=True
env = {}
@@ -134,6 +137,7 @@ def setUpModule():
check_output('systemctl stop systemd-networkd.socket')
check_output('systemctl stop systemd-networkd.service')
+ check_output('systemctl stop systemd-resolved.service')
drop_in = [
'[Service]',
@@ -164,19 +168,49 @@ def setUpModule():
with open('/run/systemd/system/systemd-networkd.service.d/00-override.conf', mode='w') as f:
f.write('\n'.join(drop_in))
+ drop_in = [
+ '[Service]',
+ 'Restart=no',
+ 'ExecStart=',
+ ]
+ if use_valgrind:
+ drop_in += ['ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + resolved_bin]
+ else:
+ drop_in += ['ExecStart=!!' + resolved_bin]
+ if enable_debug:
+ drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
+ if asan_options:
+ drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
+ if lsan_options:
+ drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
+ if ubsan_options:
+ drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
+ if asan_options or lsan_options or ubsan_options:
+ drop_in += ['SystemCallFilter=']
+ if use_valgrind or asan_options or lsan_options or ubsan_options:
+ drop_in += ['MemoryDenyWriteExecute=no']
+
+ os.makedirs('/run/systemd/system/systemd-resolved.service.d', exist_ok=True)
+ with open('/run/systemd/system/systemd-resolved.service.d/00-override.conf', mode='w') as f:
+ f.write('\n'.join(drop_in))
+
check_output('systemctl daemon-reload')
print(check_output('systemctl cat systemd-networkd.service'))
+ print(check_output('systemctl cat systemd-resolved.service'))
+ check_output('systemctl restart systemd-resolved')
def tearDownModule():
shutil.rmtree(networkd_ci_path)
check_output('systemctl stop systemd-networkd.service')
+ check_output('systemctl stop systemd-resolved.service')
shutil.rmtree('/run/systemd/system/systemd-networkd.service.d')
+ shutil.rmtree('/run/systemd/system/systemd-resolved.service.d')
check_output('systemctl daemon-reload')
check_output('systemctl start systemd-networkd.socket')
- check_output('systemctl start systemd-networkd.service')
+ check_output('systemctl start systemd-resolved.service')
def read_link_attr(link, dev, attribute):
with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
@@ -2155,6 +2189,10 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
'dhcp-client-listen-port.network',
'dhcp-client-route-metric.network',
'dhcp-client-route-table.network',
+ 'dhcp-client-use-dns-ipv4-and-ra.network',
+ 'dhcp-client-use-dns-ipv4.network',
+ 'dhcp-client-use-dns-no.network',
+ 'dhcp-client-use-dns-yes.network',
'dhcp-client-use-routes-no.network',
'dhcp-client-vrf.network',
'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network',
@@ -2676,12 +2714,87 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address2} metric 1024')
self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address2} metric 1024')
+ def test_dhcp_client_use_dns_yes(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-yes.network')
+
+ start_networkd()
+ wait_online(['veth-peer:carrier'])
+ start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
+ wait_online(['veth99:routable', 'veth-peer:routable'])
+
+ # link become 'routable' when at least one protocol provide an valid address.
+ self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+
+ time.sleep(3)
+ output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
+ print(output)
+ self.assertRegex(output, '192.168.5.1')
+ self.assertRegex(output, '2600::1')
+
+ def test_dhcp_client_use_dns_no(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-no.network')
+
+ start_networkd()
+ wait_online(['veth-peer:carrier'])
+ start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
+ wait_online(['veth99:routable', 'veth-peer:routable'])
+
+ # link become 'routable' when at least one protocol provide an valid address.
+ self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+
+ time.sleep(3)
+ output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
+ print(output)
+ self.assertNotRegex(output, '192.168.5.1')
+ self.assertNotRegex(output, '2600::1')
+
+ def test_dhcp_client_use_dns_ipv4(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-ipv4.network')
+
+ start_networkd()
+ wait_online(['veth-peer:carrier'])
+ start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
+ wait_online(['veth99:routable', 'veth-peer:routable'])
+
+ # link become 'routable' when at least one protocol provide an valid address.
+ self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+
+ time.sleep(3)
+ output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
+ print(output)
+ self.assertRegex(output, '192.168.5.1')
+ self.assertNotRegex(output, '2600::1')
+
+ def test_dhcp_client_use_dns_ipv4_and_ra(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-ipv4-and-ra.network')
+
+ start_networkd()
+ wait_online(['veth-peer:carrier'])
+ start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
+ wait_online(['veth99:routable', 'veth-peer:routable'])
+
+ # link become 'routable' when at least one protocol provide an valid address.
+ self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+
+ time.sleep(3)
+ output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
+ print(output)
+ self.assertRegex(output, '192.168.5.1')
+ self.assertRegex(output, '2600::1')
+
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
+ parser.add_argument('--resolved', help='Path to systemd-resolved', dest='resolved_bin')
parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
+ parser.add_argument('--resolvectl', help='Path to resolvectl', dest='resolvectl_bin')
+ parser.add_argument('--timedatectl', help='Path to timedatectl', dest='timedatectl_bin')
parser.add_argument('--valgrind', help='Enable valgrind', dest='use_valgrind', type=bool, nargs='?', const=True, default=use_valgrind)
parser.add_argument('--debug', help='Generate debugging logs', dest='enable_debug', type=bool, nargs='?', const=True, default=enable_debug)
parser.add_argument('--asan-options', help='ASAN options', dest='asan_options')
@@ -2690,18 +2803,27 @@ if __name__ == '__main__':
ns, args = parser.parse_known_args(namespace=unittest)
if ns.build_dir:
- if ns.networkd_bin or ns.wait_online_bin or ns.networkctl_bin:
- print('WARNING: --networkd, --wait-online, or --networkctl options are ignored when --build-dir is specified.')
+ if ns.networkd_bin or ns.resolved_bin or ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin:
+ print('WARNING: --networkd, --resolved, --wait-online, --networkctl, --resolvectl, or --timedatectl options are ignored when --build-dir is specified.')
networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
+ resolved_bin = os.path.join(ns.build_dir, 'systemd-resolved')
wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
+ resolvectl_bin = os.path.join(ns.build_dir, 'resolvectl')
+ timedatectl_bin = os.path.join(ns.build_dir, 'timedatectl')
else:
if ns.networkd_bin:
networkd_bin = ns.networkd_bin
+ if ns.resolved_bin:
+ resolved_bin = ns.resolved_bin
if ns.wait_online_bin:
wait_online_bin = ns.wait_online_bin
if ns.networkctl_bin:
networkctl_bin = ns.networkctl_bin
+ if ns.resolvectl_bin:
+ resolvectl_bin = ns.resolvectl_bin
+ if ns.timedatectl_bin:
+ timedatectl_bin = ns.timedatectl_bin
use_valgrind = ns.use_valgrind
enable_debug = ns.enable_debug
@@ -2711,9 +2833,13 @@ if __name__ == '__main__':
if use_valgrind:
networkctl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', networkctl_bin]
+ resolvectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', resolvectl_bin]
+ timedatectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', timedatectl_bin]
wait_online_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', wait_online_bin]
else:
networkctl_cmd = [networkctl_bin]
+ resolvectl_cmd = [resolvectl_bin]
+ timedatectl_cmd = [timedatectl_bin]
wait_online_cmd = [wait_online_bin]
if enable_debug: