mirror of
https://github.com/systemd/systemd.git
synced 2025-02-21 05:57:34 +03:00
Merge pull request #15443 from ddstreet/use_gateway_backwards_compatible
Make UseGateway= default backwards compatible, and fix UseGateway/RoutesToDNS
This commit is contained in:
commit
a00f28c554
@ -1491,8 +1491,9 @@
|
||||
<varlistentry>
|
||||
<term><varname>UseGateway=</varname></term>
|
||||
<listitem>
|
||||
<para>When true (the default), the gateway will be requested from the DHCP server and added to the
|
||||
routing table with a metric of 1024, and a scope of "link".</para>
|
||||
<para>When true, the gateway will be requested from the DHCP server and added to the routing table with a
|
||||
metric of 1024, and a scope of "link". When unset, the value specified with <option>UseRoutes=</option>
|
||||
is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
@ -325,78 +325,77 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!link->network->dhcp_use_gateway)
|
||||
return 0;
|
||||
if (link->network->dhcp_use_gateway) {
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (IN_SET(r, 0, -ENODATA))
|
||||
log_link_info(link, "DHCP: No gateway received from DHCP server.");
|
||||
else if (r < 0)
|
||||
log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
|
||||
else if (in4_addr_is_null(&router[0]))
|
||||
log_link_info(link, "DHCP: Received gateway is null.");
|
||||
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (IN_SET(r, 0, -ENODATA))
|
||||
log_link_info(link, "DHCP: No gateway received from DHCP server.");
|
||||
else if (r < 0)
|
||||
log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
|
||||
else if (in4_addr_is_null(&router[0]))
|
||||
log_link_info(link, "DHCP: Received gateway is null.");
|
||||
/* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
|
||||
a Router option, the DHCP client MUST ignore the Router option. */
|
||||
if (classless_route && static_route)
|
||||
log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option and router option");
|
||||
|
||||
/* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
|
||||
a Router option, the DHCP client MUST ignore the Router option. */
|
||||
if (classless_route && static_route)
|
||||
log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option and router option");
|
||||
if (r > 0 && !classless_route && !in4_addr_is_null(&router[0])) {
|
||||
_cleanup_(route_freep) Route *route = NULL, *route_gw = NULL;
|
||||
|
||||
if (r > 0 && !classless_route && !in4_addr_is_null(&router[0])) {
|
||||
_cleanup_(route_freep) Route *route = NULL, *route_gw = NULL;
|
||||
r = route_new(&route_gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
|
||||
r = route_new(&route_gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
/* The dhcp netmask may mask out the gateway. Add an explicit
|
||||
* route for the gw host so that we can route no matter the
|
||||
* netmask or existing kernel route tables. */
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->prefsrc.in = address;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
route_gw->protocol = RTPROT_DHCP;
|
||||
route_gw->priority = link->network->dhcp_route_metric;
|
||||
route_gw->table = table;
|
||||
route_gw->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
/* The dhcp netmask may mask out the gateway. Add an explicit
|
||||
* route for the gw host so that we can route no matter the
|
||||
* netmask or existing kernel route tables. */
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->prefsrc.in = address;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
route_gw->protocol = RTPROT_DHCP;
|
||||
route_gw->priority = link->network->dhcp_route_metric;
|
||||
route_gw->table = table;
|
||||
route_gw->mtu = link->network->dhcp_route_mtu;
|
||||
r = dhcp_route_configure(&route_gw, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set host route: %m");
|
||||
|
||||
r = dhcp_route_configure(&route_gw, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set host route: %m");
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
route->family = AF_INET;
|
||||
route->gw.in = router[0];
|
||||
route->prefsrc.in = address;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
route->family = AF_INET;
|
||||
route->gw.in = router[0];
|
||||
route->prefsrc.in = address;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
r = dhcp_route_configure(&route, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set router: %m");
|
||||
}
|
||||
|
||||
r = dhcp_route_configure(&route, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set router: %m");
|
||||
}
|
||||
Route *rt;
|
||||
LIST_FOREACH(routes, rt, link->network->static_routes) {
|
||||
if (!rt->gateway_from_dhcp)
|
||||
continue;
|
||||
|
||||
Route *rt;
|
||||
LIST_FOREACH(routes, rt, link->network->static_routes) {
|
||||
if (!rt->gateway_from_dhcp)
|
||||
continue;
|
||||
if (rt->family != AF_INET)
|
||||
continue;
|
||||
|
||||
if (rt->family != AF_INET)
|
||||
continue;
|
||||
rt->gw.in = router[0];
|
||||
|
||||
rt->gw.in = router[0];
|
||||
|
||||
r = route_configure(rt, link, dhcp4_route_handler);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set gateway: %m");
|
||||
if (r > 0)
|
||||
link->dhcp4_messages++;
|
||||
r = route_configure(rt, link, dhcp4_route_handler);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set gateway: %m");
|
||||
if (r > 0)
|
||||
link->dhcp4_messages++;
|
||||
}
|
||||
}
|
||||
|
||||
return link_set_dns_routes(link, &address);
|
||||
|
@ -164,7 +164,7 @@ DHCPv4.UseMTU, config_parse_bool,
|
||||
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.UseGateway, config_parse_bool, 0, offsetof(Network, dhcp_use_gateway)
|
||||
DHCPv4.UseGateway, config_parse_tristate, 0, offsetof(Network, dhcp_use_gateway)
|
||||
DHCPv4.RequestOptions, config_parse_dhcp_request_options, 0, 0
|
||||
DHCPv4.Anonymize, config_parse_bool, 0, offsetof(Network, dhcp_anonymize)
|
||||
DHCPv4.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_send_hostname)
|
||||
|
@ -267,6 +267,9 @@ int network_verify(Network *network) {
|
||||
network->dhcp_use_mtu = false;
|
||||
}
|
||||
|
||||
if (network->dhcp_use_gateway < 0)
|
||||
network->dhcp_use_gateway = network->dhcp_use_routes;
|
||||
|
||||
if (network->dhcp_critical >= 0) {
|
||||
if (network->keep_configuration >= 0)
|
||||
log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
|
||||
@ -385,7 +388,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
.dhcp_use_dns = true,
|
||||
.dhcp_use_hostname = true,
|
||||
.dhcp_use_routes = true,
|
||||
.dhcp_use_gateway = true,
|
||||
.dhcp_use_gateway = -1,
|
||||
/* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
|
||||
.dhcp_send_hostname = true,
|
||||
.dhcp_send_release = true,
|
||||
|
@ -110,7 +110,7 @@ struct Network {
|
||||
bool dhcp_use_sip;
|
||||
bool dhcp_use_mtu;
|
||||
bool dhcp_use_routes;
|
||||
bool dhcp_use_gateway;
|
||||
int dhcp_use_gateway;
|
||||
bool dhcp_use_timezone;
|
||||
bool rapid_commit;
|
||||
bool dhcp_use_hostname;
|
||||
|
@ -1,9 +0,0 @@
|
||||
[Match]
|
||||
Name=veth99
|
||||
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
IPv6AcceptRA=false
|
||||
|
||||
[DHCPv4]
|
||||
UseGateway=no
|
@ -4,6 +4,3 @@ Name=veth99
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
IPv6AcceptRA=false
|
||||
|
||||
[DHCPv4]
|
||||
UseRoutes=no
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
RoutesToDNS=no
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
RoutesToDNS=yes
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
UseGateway=no
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
UseGateway=yes
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
UseRoutes=no
|
@ -0,0 +1,2 @@
|
||||
[DHCPv4]
|
||||
UseRoutes=yes
|
@ -3,6 +3,7 @@
|
||||
# systemd-networkd tests
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@ -2921,8 +2922,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
'dhcp-client-ipv4-dhcp-settings.network',
|
||||
'dhcp-client-ipv4-only-ipv6-disabled.network',
|
||||
'dhcp-client-ipv4-only.network',
|
||||
'dhcp-client-ipv4-use-gateway-no.network',
|
||||
'dhcp-client-ipv4-use-routes-no.network',
|
||||
'dhcp-client-ipv4-use-routes-use-gateway.network',
|
||||
'dhcp-client-ipv6-only.network',
|
||||
'dhcp-client-ipv6-rapid-commit.network',
|
||||
'dhcp-client-keep-configuration-dhcp-on-stop.network',
|
||||
@ -2937,7 +2937,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
'dhcp-client-use-dns-no.network',
|
||||
'dhcp-client-use-dns-yes.network',
|
||||
'dhcp-client-use-domains.network',
|
||||
'dhcp-client-use-routes-no.network',
|
||||
'dhcp-client-vrf.network',
|
||||
'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network',
|
||||
'dhcp-client-with-ipv4ll-fallback-without-dhcp-server.network',
|
||||
@ -2946,7 +2945,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
'dhcp-server-decline.network',
|
||||
'dhcp-server-veth-peer.network',
|
||||
'dhcp-v4-server-veth-peer.network',
|
||||
'dhcp-client-use-domains.network',
|
||||
'static.network']
|
||||
|
||||
def setUp(self):
|
||||
@ -3027,8 +3025,23 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||
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_no(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-use-routes-no.network')
|
||||
def test_dhcp_client_ipv4_use_routes_gateway(self):
|
||||
for (routes, gateway, dnsroutes) in itertools.product([True, False, None], repeat=3):
|
||||
self.setUp()
|
||||
with self.subTest(routes=routes, gateway=gateway, dnsroutes=dnsroutes):
|
||||
self._test_dhcp_client_ipv4_use_routes_gateway(routes, gateway, dnsroutes)
|
||||
self.tearDown()
|
||||
|
||||
def _test_dhcp_client_ipv4_use_routes_gateway(self, routes, gateway, dnsroutes):
|
||||
testunit = 'dhcp-client-ipv4-use-routes-use-gateway.network'
|
||||
testunits = ['25-veth.netdev', 'dhcp-server-veth-peer.network', testunit]
|
||||
if routes != None:
|
||||
testunits.append(f'{testunit}.d/use-routes-{routes}.conf');
|
||||
if gateway != None:
|
||||
testunits.append(f'{testunit}.d/use-gateway-{gateway}.conf');
|
||||
if dnsroutes != None:
|
||||
testunits.append(f'{testunit}.d/use-dns-routes-{dnsroutes}.conf');
|
||||
copy_unit_to_networkd_unit_path(*testunits, dropins=False)
|
||||
|
||||
start_networkd()
|
||||
self.wait_online(['veth-peer:carrier'])
|
||||
@ -3037,22 +3050,31 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
|
||||
output = check_output('ip route show dev veth99')
|
||||
print(output)
|
||||
self.assertNotRegex(output, r'192.168.5.5')
|
||||
self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.181 metric 1024')
|
||||
self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||
|
||||
def test_dhcp_client_ipv4_use_gateway_no(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-use-gateway-no.network')
|
||||
# UseRoutes= defaults to true
|
||||
useroutes = routes in [True, None]
|
||||
# UseGateway= defaults to useroutes
|
||||
usegateway = useroutes if gateway == None else gateway
|
||||
|
||||
start_networkd()
|
||||
self.wait_online(['veth-peer:carrier'])
|
||||
start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7', lease_time='2m')
|
||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
# Check UseRoutes=
|
||||
if useroutes:
|
||||
self.assertRegex(output, r'192.168.5.0/24 via 192.168.5.5 proto dhcp src 192.168.5.181 metric 1024')
|
||||
else:
|
||||
self.assertNotRegex(output, r'192.168.5.5')
|
||||
|
||||
output = check_output('ip route show dev veth99')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.0/24 via 192.168.5.5 proto dhcp src 192.168.5.181 metric 1024')
|
||||
self.assertNotRegex(output, r'default via 192.168.5.1')
|
||||
# Check UseGateway=
|
||||
if usegateway:
|
||||
self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.181 metric 1024')
|
||||
else:
|
||||
self.assertNotRegex(output, r'default via 192.168.5.1')
|
||||
|
||||
# Check RoutesToDNS=, which defaults to false
|
||||
if dnsroutes:
|
||||
self.assertRegex(output, r'192.168.5.6 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||
self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||
else:
|
||||
self.assertNotRegex(output, r'192.168.5.6')
|
||||
self.assertNotRegex(output, r'192.168.5.7')
|
||||
|
||||
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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user