Merge pull request #19374 from yuwata/network-dhcp-routes-to-ntp

network: dhcp4: introduce RoutesToNTP= boolean setting
This commit is contained in:
Lennart Poettering 2021-04-28 22:47:21 +02:00 committed by GitHub
commit fd98562099
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 90 additions and 26 deletions

View file

@ -1631,7 +1631,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<listitem>
<para>When true, the routes to the DNS servers received from the DHCP server will be
configured. When <varname>UseDNS=</varname> is disabled, this setting is ignored.
Defaults to false.</para>
Defaults to true.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1641,6 +1641,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<filename>systemd-timesyncd.service</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RoutesToNTP=</varname></term>
<listitem>
<para>When true, the routes to the NTP servers received from the DHCP server will be
configured. When <varname>UseNTP=</varname> is disabled, this setting is ignored.
Defaults to true.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseSIP=</varname></term>
<listitem>

View file

@ -487,26 +487,21 @@ static int link_set_dhcp_gateway(Link *link, struct in_addr *ret_gw) {
return 0;
}
static int link_set_dns_routes(Link *link, const struct in_addr *gw) {
static int link_set_routes_to_servers(
Link *link,
const struct in_addr *servers,
size_t n_servers,
const struct in_addr *gw) {
_cleanup_(route_freep) Route *route = NULL;
const struct in_addr *dns;
int n, r;
int r;
assert(link);
assert(link->dhcp_lease);
assert(link->network);
assert(servers || n_servers == 0);
assert(gw);
if (!link->network->dhcp_use_dns ||
!link->network->dhcp_routes_to_dns)
return 0;
n = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns);
if (IN_SET(n, 0, -ENODATA))
return 0;
if (n < 0)
return n;
r = route_new(&route);
if (r < 0)
return r;
@ -518,11 +513,11 @@ static int link_set_dns_routes(Link *link, const struct in_addr *gw) {
route->table = link_get_dhcp_route_table(link);
route->mtu = link->network->dhcp_route_mtu;
for (int i = 0; i < n; i ++) {
if (in4_addr_is_null(&dns[i]))
for (size_t i = 0; i < n_servers; i++) {
if (in4_addr_is_null(&servers[i]))
continue;
route->dst.in = dns[i];
route->dst.in = servers[i];
r = dhcp_route_configure_auto(route, link, gw);
if (r < 0)
@ -532,6 +527,50 @@ static int link_set_dns_routes(Link *link, const struct in_addr *gw) {
return 0;
}
static int link_set_routes_to_dns(Link *link, const struct in_addr *gw) {
const struct in_addr *dns;
int r;
assert(link);
assert(link->dhcp_lease);
assert(link->network);
assert(gw);
if (!link->network->dhcp_use_dns ||
!link->network->dhcp_routes_to_dns)
return 0;
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns);
if (IN_SET(r, 0, -ENODATA))
return 0;
if (r < 0)
return r;
return link_set_routes_to_servers(link, dns, r, gw);
}
static int link_set_routes_to_ntp(Link *link, const struct in_addr *gw) {
const struct in_addr *ntp;
int r;
assert(link);
assert(link->dhcp_lease);
assert(link->network);
assert(gw);
if (!link->network->dhcp_use_ntp ||
!link->network->dhcp_routes_to_ntp)
return 0;
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp);
if (IN_SET(r, 0, -ENODATA))
return 0;
if (r < 0)
return r;
return link_set_routes_to_servers(link, ntp, r, gw);
}
static int link_set_dhcp_routes(Link *link) {
struct in_addr gw = {};
Route *rt;
@ -571,10 +610,14 @@ static int link_set_dhcp_routes(Link *link) {
return log_link_error_errno(link, r, "DHCP error: Could not set gateway: %m");
}
r = link_set_dns_routes(link, &gw);
r = link_set_routes_to_dns(link, &gw);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: Could not set routes to DNS servers: %m");
r = link_set_routes_to_ntp(link, &gw);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: Could not set routes to NTP servers: %m");
return 0;
}

View file

@ -198,6 +198,7 @@ DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier
DHCPv4.UseDNS, config_parse_dhcp_use_dns, 0, 0
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
DHCPv4.UseNTP, config_parse_dhcp_use_ntp, 0, 0
DHCPv4.RoutesToNTP, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_ntp)
DHCPv4.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp_use_sip)
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)

View file

@ -304,8 +304,10 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_duid.type = _DUID_TYPE_INVALID,
.dhcp_critical = -1,
.dhcp_use_ntp = true,
.dhcp_routes_to_ntp = true,
.dhcp_use_sip = true,
.dhcp_use_dns = true,
.dhcp_routes_to_dns = true,
.dhcp_use_hostname = true,
.dhcp_use_routes = true,
.dhcp_use_gateway = -1,

View file

@ -142,6 +142,7 @@ struct Network {
bool dhcp_routes_to_dns;
bool dhcp_use_ntp;
bool dhcp_use_ntp_set;
bool dhcp_routes_to_ntp;
bool dhcp_use_sip;
bool dhcp_use_mtu;
bool dhcp_use_routes;

View file

@ -95,6 +95,7 @@ UseGateway=
IAID=
UserClass=
UseNTP=
RoutesToNTP=
UseSIP=
UseMTU=
UseDomainName=

View file

@ -3852,23 +3852,23 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.assertRegex(output, r'192.168.5.8 proto dhcp scope link src 192.168.5.181 metric 1024')
def test_dhcp_client_ipv4_use_routes_gateway(self):
for (routes, gateway, dnsroutes, classless) in itertools.product([True, False], repeat=4):
for (routes, gateway, dns_and_ntp_routes, classless) in itertools.product([True, False], repeat=4):
self.setUp()
with self.subTest(routes=routes, gateway=gateway, dnsroutes=dnsroutes, classless=classless):
self._test_dhcp_client_ipv4_use_routes_gateway(routes, gateway, dnsroutes, classless)
with self.subTest(routes=routes, gateway=gateway, dns_and_ntp_routes=dns_and_ntp_routes, classless=classless):
self._test_dhcp_client_ipv4_use_routes_gateway(routes, gateway, dns_and_ntp_routes, classless)
self.tearDown()
def _test_dhcp_client_ipv4_use_routes_gateway(self, use_routes, use_gateway, dnsroutes, classless):
def _test_dhcp_client_ipv4_use_routes_gateway(self, use_routes, use_gateway, dns_and_ntp_routes, classless):
testunit = 'dhcp-client-ipv4-use-routes-use-gateway.network'
testunits = ['25-veth.netdev', 'dhcp-server-veth-peer.network', testunit]
testunits.append(f'{testunit}.d/use-routes-{use_routes}.conf');
testunits.append(f'{testunit}.d/use-gateway-{use_gateway}.conf');
testunits.append(f'{testunit}.d/use-dns-routes-{dnsroutes}.conf');
testunits.append(f'{testunit}.d/use-dns-and-ntp-routes-{dns_and_ntp_routes}.conf');
copy_unit_to_networkd_unit_path(*testunits, dropins=False)
start_networkd()
self.wait_online(['veth-peer:carrier'])
additional_options = '--dhcp-option=option:dns-server,192.168.5.10,8.8.8.8 --dhcp-option=option:static-route,192.168.5.100,192.168.5.2,8.8.8.8,192.168.5.3'
additional_options = '--dhcp-option=option:dns-server,192.168.5.10,8.8.8.8 --dhcp-option=option:ntp-server,192.168.5.11,9.9.9.9 --dhcp-option=option:static-route,192.168.5.100,192.168.5.2,8.8.8.8,192.168.5.3'
if classless:
additional_options += ' --dhcp-option=option:classless-static-route,0.0.0.0/0,192.168.5.4,8.0.0.0/8,192.168.5.5'
start_dnsmasq(additional_options=additional_options, lease_time='2m')
@ -3905,18 +3905,24 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
# Check RoutesToDNS=
if dnsroutes:
# Check RoutesToDNS= and RoutesToNTP=
if dns_and_ntp_routes:
self.assertRegex(output, r'192.168.5.10 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertRegex(output, r'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
if classless and use_routes:
self.assertRegex(output, r'8.8.8.8 via 192.168.5.4 proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertRegex(output, r'9.9.9.9 via 192.168.5.4 proto dhcp src 192.168.5.[0-9]* metric 1024')
elif use_gateway:
self.assertRegex(output, r'8.8.8.8 via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertRegex(output, r'9.9.9.9 via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
else:
self.assertNotRegex(output, r'8.8.8.8 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'9.9.9.9 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
else:
self.assertNotRegex(output, r'192.168.5.10 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'8.8.8.8 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'9.9.9.9 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
def test_dhcp_client_ipv4_ipv6(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',