diff options
-rw-r--r-- | man/systemd.network.xml | 43 | ||||
-rw-r--r-- | src/network/networkd-dhcp-common.c | 66 | ||||
-rw-r--r-- | src/network/networkd-dhcp-common.h | 2 | ||||
-rw-r--r-- | src/network/networkd-link.c | 4 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 84 | ||||
-rw-r--r-- | src/network/networkd-network.c | 4 | ||||
-rw-r--r-- | src/network/networkd-network.h | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-network-parser/directives.network | 39 | ||||
-rw-r--r-- | test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network | 11 | ||||
-rw-r--r-- | test/test-network/conf/dhcp-client-use-dns-ipv4.network | 14 | ||||
-rw-r--r-- | test/test-network/conf/dhcp-client-use-dns-no.network | 11 | ||||
-rw-r--r-- | test/test-network/conf/dhcp-client-use-dns-yes.network | 11 | ||||
-rwxr-xr-x | test/test-network/systemd-networkd-tests.py | 132 |
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: |