mirror of
https://github.com/systemd/systemd
synced 2026-03-22 23:04:52 +01:00
Compare commits
4 Commits
77976a6877
...
6c39b39aa8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c39b39aa8 | ||
|
|
4df8a8e809 | ||
|
|
87e62d32b4 | ||
|
|
0ebab55f4f |
@ -379,9 +379,6 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
|||||||
assert(link->dhcp_lease);
|
assert(link->dhcp_lease);
|
||||||
assert(ret_default_gw);
|
assert(ret_default_gw);
|
||||||
|
|
||||||
if (!link->network->dhcp_use_routes)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
|
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
|
||||||
if (IN_SET(n, 0, -ENODATA)) {
|
if (IN_SET(n, 0, -ENODATA)) {
|
||||||
log_link_debug(link, "DHCP: No static routes received from DHCP server.");
|
log_link_debug(link, "DHCP: No static routes received from DHCP server.");
|
||||||
@ -406,6 +403,45 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
|||||||
if (classless_route && static_route)
|
if (classless_route && static_route)
|
||||||
log_link_debug(link, "Classless static routes received from DHCP server: ignoring static-route option");
|
log_link_debug(link, "Classless static routes received from DHCP server: ignoring static-route option");
|
||||||
|
|
||||||
|
if (!link->network->dhcp_use_routes) {
|
||||||
|
if (!classless_route)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Even if UseRoutes=no, try to find default gateway to make semi-static routes and
|
||||||
|
* routes to DNS or NTP servers can be configured in later steps. */
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
struct in_addr dst;
|
||||||
|
uint8_t prefixlen;
|
||||||
|
|
||||||
|
if (sd_dhcp_route_get_option(static_routes[i]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = sd_dhcp_route_get_destination(static_routes[i], &dst);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (in4_addr_is_set(&dst))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = sd_dhcp_route_get_destination_prefix_length(static_routes[i], &prefixlen);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (prefixlen != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = sd_dhcp_route_get_gateway(static_routes[i], ret_default_gw);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not return 1 here, to ensure the router option can override the default gateway
|
||||||
|
* that was found. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
_cleanup_(route_freep) Route *route = NULL;
|
_cleanup_(route_freep) Route *route = NULL;
|
||||||
struct in_addr gw;
|
struct in_addr gw;
|
||||||
@ -454,19 +490,15 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
|||||||
return classless_route;
|
return classless_route;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
static int dhcp4_request_gateway(Link *link, struct in_addr *gw) {
|
||||||
_cleanup_(route_freep) Route *route = NULL;
|
_cleanup_(route_freep) Route *route = NULL;
|
||||||
const struct in_addr *router;
|
const struct in_addr *router;
|
||||||
struct in_addr address;
|
struct in_addr address;
|
||||||
Route *rt;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->dhcp_lease);
|
assert(link->dhcp_lease);
|
||||||
assert(ret_gw);
|
assert(gw);
|
||||||
|
|
||||||
if (!link->network->dhcp_use_gateway)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -484,6 +516,16 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!link->network->dhcp_use_gateway) {
|
||||||
|
/* When no classless static route is provided, even if UseGateway=no, use the gateway
|
||||||
|
* address to configure semi-static routes or routes to DNS or NTP servers. Note, if
|
||||||
|
* neither UseRoutes= nor UseGateway= is disabled, use the default gateway in classless
|
||||||
|
* static routes if provided (in that case, in4_addr_is_null(gw) below is true). */
|
||||||
|
if (in4_addr_is_null(gw))
|
||||||
|
*gw = router[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
|
/* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
|
||||||
* so that we can route no matter the netmask or existing kernel route tables. */
|
* so that we can route no matter the netmask or existing kernel route tables. */
|
||||||
r = dhcp4_request_route_to_gateway(link, &router[0]);
|
r = dhcp4_request_route_to_gateway(link, &router[0]);
|
||||||
@ -508,18 +550,42 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* When no classless static route is provided, or UseRoutes=no, then use the router address to
|
||||||
|
* configure semi-static routes and routes to DNS or NTP servers in later steps. */
|
||||||
|
*gw = router[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcp4_request_semi_static_routes(Link *link, const struct in_addr *gw) {
|
||||||
|
Route *rt;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->dhcp_lease);
|
||||||
|
assert(link->network);
|
||||||
|
assert(gw);
|
||||||
|
|
||||||
|
if (in4_addr_is_null(gw))
|
||||||
|
return 0;
|
||||||
|
|
||||||
HASHMAP_FOREACH(rt, link->network->routes_by_section) {
|
HASHMAP_FOREACH(rt, link->network->routes_by_section) {
|
||||||
|
_cleanup_(route_freep) Route *route = NULL;
|
||||||
|
|
||||||
if (!rt->gateway_from_dhcp_or_ra)
|
if (!rt->gateway_from_dhcp_or_ra)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rt->gw_family != AF_INET)
|
if (rt->gw_family != AF_INET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
r = dhcp4_request_route_to_gateway(link, gw);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = route_dup(rt, &route);
|
r = route_dup(rt, &route);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
route->gw.in = router[0];
|
route->gw.in = *gw;
|
||||||
if (!route->protocol_set)
|
if (!route->protocol_set)
|
||||||
route->protocol = RTPROT_DHCP;
|
route->protocol = RTPROT_DHCP;
|
||||||
if (!route->priority_set)
|
if (!route->priority_set)
|
||||||
@ -534,7 +600,6 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_gw = router[0];
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +718,10 @@ static int dhcp4_request_routes(Link *link) {
|
|||||||
return log_link_error_errno(link, r, "DHCP error: Could not request gateway: %m");
|
return log_link_error_errno(link, r, "DHCP error: Could not request gateway: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = dhcp4_request_semi_static_routes(link, &gw);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "DHCP error: Could not request routes with Gateway=_dhcp4 setting: %m");
|
||||||
|
|
||||||
r = dhcp4_request_routes_to_dns(link, &gw);
|
r = dhcp4_request_routes_to_dns(link, &gw);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "DHCP error: Could not request routes to DNS servers: %m");
|
return log_link_error_errno(link, r, "DHCP error: Could not request routes to DNS servers: %m");
|
||||||
|
|||||||
@ -4017,9 +4017,13 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
# Check UseGateway=
|
# Check UseGateway=
|
||||||
if use_gateway and (not classless or not use_routes):
|
if use_gateway and (not classless or not use_routes):
|
||||||
self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
|
self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
|
||||||
self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
|
|
||||||
else:
|
else:
|
||||||
self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
|
self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
|
||||||
|
|
||||||
|
# Check route to gateway
|
||||||
|
if (use_gateway or dns_and_ntp_routes) and (not classless or not use_routes):
|
||||||
|
self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
|
||||||
|
else:
|
||||||
self.assertNotRegex(output, r'192.168.5.1 proto dhcp scope link 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= and RoutesToNTP=
|
# Check RoutesToDNS= and RoutesToNTP=
|
||||||
@ -4029,12 +4033,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
if classless and use_routes:
|
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'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')
|
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:
|
else:
|
||||||
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'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')
|
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:
|
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.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'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
|
||||||
@ -4425,9 +4426,24 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
start_dnsmasq()
|
start_dnsmasq()
|
||||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||||
|
|
||||||
output = check_output('ip route list dev veth99 10.0.0.0/8')
|
output = check_output('ip route list dev veth99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto dhcp')
|
self.assertRegex(output, 'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]*')
|
||||||
|
self.assertIn('10.0.0.0/8 via 192.168.5.1 proto dhcp', output)
|
||||||
|
|
||||||
|
with open(os.path.join(network_unit_file_path, 'dhcp-client-gateway-ipv4.network'), mode='a') as f:
|
||||||
|
f.write('[DHCPv4]\nUseGateway=no\n')
|
||||||
|
|
||||||
|
rc = call(*networkctl_cmd, 'reload', env=env)
|
||||||
|
self.assertEqual(rc, 0)
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||||
|
|
||||||
|
output = check_output('ip route list dev veth99')
|
||||||
|
print(output)
|
||||||
|
self.assertNotRegex(output, 'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]*')
|
||||||
|
self.assertIn('10.0.0.0/8 via 192.168.5.1 proto dhcp', output)
|
||||||
|
|
||||||
def test_dhcp_client_gateway_ipv6(self):
|
def test_dhcp_client_gateway_ipv6(self):
|
||||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
|
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user