network: add mechanism to configure default UseDomains= setting, update man page and add test

This commit is contained in:
Henry Li 2024-04-09 17:40:42 -07:00
parent 5152b8459a
commit fb57300743
9 changed files with 77 additions and 1 deletions

View file

@ -256,6 +256,17 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
<xi:include href="version-info.xml" xpointer="v230"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseDomains=</varname></term>
<listitem><para>Specifies the default value for per-network <varname>UseDomains=</varname>.
Takes a boolean. See for details in
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
Defaults to <literal>no</literal>.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -280,6 +291,13 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
<xi:include href="version-info.xml" xpointer="v249"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>UseDomains=</varname></term>
<listitem><para>As in the [DHCPv4] section.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
</variablelist>
</refsect1>

View file

@ -2570,7 +2570,9 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
effect of the <option>Domains=</option> setting. If set to <option>route</option>, the domain name
received from the DHCP server will be used for routing DNS queries only, but not for searching,
similarly to the effect of the <option>Domains=</option> setting when the argument is prefixed with
<literal>~</literal>. Defaults to false.</para>
<literal>~</literal>. When unspecified, the value specified in the same setting in
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which defaults to <literal>no</literal>, will be used.</para>
<para>It is recommended to enable this option only on trusted networks, as setting this
affects resolution of all hostnames, in particular of single-label names. It is generally

View file

@ -632,6 +632,8 @@ int config_parse_dhcp_use_domains(
return 0;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_default_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse UseDomains=")
int config_parse_dhcp_use_ntp(
const char* unit,
const char *filename,

View file

@ -99,6 +99,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_route_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_hostname);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_default_dhcp_use_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_or_ra_route_table);

View file

@ -30,8 +30,10 @@ Network.RouteTable, config_parse_route_table_names,
Network.IPv4Forwarding, config_parse_tristate, 0, offsetof(Manager, ip_forwarding[0])
Network.IPv6Forwarding, config_parse_tristate, 0, offsetof(Manager, ip_forwarding[1])
Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Manager, ipv6_privacy_extensions)
DHCPv4.UseDomains, config_parse_default_dhcp_use_domains, 0, offsetof(Manager, dhcp_use_domains)
DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp_duid)
DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp_duid)
DHCPv6.UseDomains, config_parse_default_dhcp_use_domains, 0, offsetof(Manager, dhcp6_use_domains)
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp6_duid)
DHCPServer.PersistLeases, config_parse_bool, 0, offsetof(Manager, dhcp_server_persist_leases)

View file

@ -64,6 +64,9 @@ struct Manager {
OrderedSet *address_pools;
Set *dhcp_pd_subnet_ids;
DHCPUseDomains dhcp_use_domains;
DHCPUseDomains dhcp6_use_domains;
DUID dhcp_duid;
DUID dhcp6_duid;
DUID duid_product_uuid;

View file

@ -388,6 +388,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_use_captive_portal = true,
.dhcp_use_dns = true,
.dhcp_routes_to_dns = true,
.dhcp_use_domains = manager->dhcp_use_domains,
.dhcp_use_hostname = true,
.dhcp_use_routes = true,
.dhcp_use_gateway = -1,
@ -404,6 +405,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_use_address = true,
.dhcp6_use_pd_prefix = true,
.dhcp6_use_dns = true,
.dhcp6_use_domains = manager->dhcp6_use_domains,
.dhcp6_use_hostname = true,
.dhcp6_use_ntp = true,
.dhcp6_use_captive_portal = true,

View file

@ -28,10 +28,12 @@
[DHCPv4]
#DUIDType=vendor
#DUIDRawData=
#UseDomains=no
[DHCPv6]
#DUIDType=vendor
#DUIDRawData=
#UseDomains=no
[DHCPServer]
#PersistLeases=yes

View file

@ -6839,6 +6839,50 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
check(self, True, False)
check(self, False, True)
check(self, False, False)
def test_dhcp_client_default_use_domains(self):
def check(self, ipv4, ipv6):
mkdir_p(networkd_conf_dropin_dir)
with open(os.path.join(networkd_conf_dropin_dir, 'default_use_domains.conf'), mode='w', encoding='utf-8') as f:
f.write('[DHCPv4]\nUseDomains=')
f.write('yes\n' if ipv4 else 'no\n')
f.write('[DHCPv6]\nUseDomains=')
f.write('yes\n' if ipv6 else 'no\n')
restart_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1',
'--dhcp-option=option6:dns-server,[2600::1]',
'--dhcp-option=option:domain-search,example.com',
'--dhcp-option=option6:domain-search,example.com')
self.wait_online('veth99:routable')
# link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
for _ in range(20):
output = resolvectl('domain', 'veth99')
if ipv4 or ipv6:
if 'example.com' in output:
break
else:
if 'example.com' not in output:
break
time.sleep(0.5)
else:
print(output)
self.fail('unexpected domain setting in resolved...')
stop_dnsmasq()
remove_networkd_conf_dropin('default_use_domains.conf')
copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
check(self, True, True)
check(self, True, False)
check(self, False, True)
check(self, False, False)
def test_dhcp_client_use_captive_portal(self):
def check(self, ipv4, ipv6):