Merge pull request #14499 from yuwata/network-gateway-dhcp
network: static route via DHCP gateway
This commit is contained in:
commit
65ad4ad89d
|
@ -1216,7 +1216,9 @@
|
|||
<varlistentry>
|
||||
<term><varname>Gateway=</varname></term>
|
||||
<listitem>
|
||||
<para>As in the <literal>[Network]</literal> section.</para>
|
||||
<para>Takes the gateway address or special value <literal>dhcp</literal>. If
|
||||
<literal>dhcp</literal>, then the gateway address provided by DHCP (or in the IPv6 case,
|
||||
provided by IPv6 RA) is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
|
|
@ -377,6 +377,23 @@ static int link_set_dhcp_routes(Link *link) {
|
|||
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;
|
||||
|
||||
if (rt->family != AF_INET)
|
||||
continue;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
return link_set_dns_routes(link, &address);
|
||||
}
|
||||
|
||||
|
@ -480,6 +497,20 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
|
|||
if (remove_all || !set_contains(link->dhcp_routes, route))
|
||||
(void) route_remove(route, link, NULL);
|
||||
|
||||
Route *rt;
|
||||
LIST_FOREACH(routes, rt, link->network->static_routes) {
|
||||
if (!rt->gateway_from_dhcp)
|
||||
continue;
|
||||
|
||||
if (rt->family != AF_INET)
|
||||
continue;
|
||||
|
||||
if (!remove_all && in4_addr_equal(router, &rt->gw.in))
|
||||
continue;
|
||||
|
||||
(void) route_remove(rt, link, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1039,6 +1039,8 @@ int link_request_set_routes(Link *link) {
|
|||
/* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
|
||||
for (phase = 0; phase < _PHASE_MAX; phase++)
|
||||
LIST_FOREACH(routes, rt, link->network->static_routes) {
|
||||
if (rt->gateway_from_dhcp)
|
||||
continue;
|
||||
|
||||
if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
|
||||
continue;
|
||||
|
|
|
@ -169,6 +169,26 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
|||
if (r > 0)
|
||||
link->ndisc_messages++;
|
||||
|
||||
Route *route_gw;
|
||||
LIST_FOREACH(routes, route_gw, link->network->static_routes) {
|
||||
if (!route_gw->gateway_from_dhcp)
|
||||
continue;
|
||||
|
||||
if (route_gw->family != AF_INET6)
|
||||
continue;
|
||||
|
||||
route_gw->gw = gateway;
|
||||
|
||||
r = route_configure(route_gw, link, ndisc_netlink_route_message_handler);
|
||||
if (r < 0) {
|
||||
log_link_error_errno(link, r, "Could not set gateway: %m");
|
||||
link_enter_failed(link);
|
||||
return r;
|
||||
}
|
||||
if (r > 0)
|
||||
link->ndisc_messages++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -998,10 +998,19 @@ int config_parse_gateway(
|
|||
/* we are not in an Route section, so treat
|
||||
* this as the special '0' section */
|
||||
r = route_new_static(network, NULL, 0, &n);
|
||||
} else
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(rvalue, "dhcp")) {
|
||||
n->gateway_from_dhcp = true;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (n->family == AF_UNSPEC)
|
||||
r = in_addr_from_string_auto(rvalue, &n->family, &n->gw);
|
||||
|
|
|
@ -48,6 +48,7 @@ struct Route {
|
|||
unsigned char pref;
|
||||
unsigned flags;
|
||||
int gateway_onlink;
|
||||
bool gateway_from_dhcp;
|
||||
|
||||
union in_addr_union gw;
|
||||
union in_addr_union dst;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[Match]
|
||||
Name=veth99
|
||||
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
IPv6AcceptRA=no
|
||||
|
||||
[Route]
|
||||
Gateway=dhcp
|
||||
Destination=10.0.0.0/8
|
|
@ -0,0 +1,9 @@
|
|||
[Match]
|
||||
Name=veth99
|
||||
|
||||
[Network]
|
||||
DHCP=ipv6
|
||||
|
||||
[Route]
|
||||
Gateway=dhcp
|
||||
Destination=2001:1234:5:9fff:ff:ff:ff:ff/128
|
|
@ -2659,6 +2659,8 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||
'25-vrf.network',
|
||||
'dhcp-client-anonymize.network',
|
||||
'dhcp-client-decline.network',
|
||||
'dhcp-client-gateway-ipv4.network',
|
||||
'dhcp-client-gateway-ipv6.network',
|
||||
'dhcp-client-gateway-onlink-implicit.network',
|
||||
'dhcp-client-ipv4-dhcp-settings.network',
|
||||
'dhcp-client-ipv4-only-ipv6-disabled.network',
|
||||
|
@ -3145,6 +3147,30 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
def test_dhcp_client_gateway_ipv4(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
|
||||
'dhcp-client-gateway-ipv4.network')
|
||||
start_networkd()
|
||||
self.wait_online(['veth-peer:carrier'])
|
||||
start_dnsmasq()
|
||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
output = check_output('ip route list dev veth99 10.0.0.0/8')
|
||||
print(output)
|
||||
self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto static')
|
||||
|
||||
def test_dhcp_client_gateway_ipv6(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
|
||||
'dhcp-client-gateway-ipv6.network')
|
||||
start_networkd()
|
||||
self.wait_online(['veth-peer:carrier'])
|
||||
start_dnsmasq()
|
||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
output = check_output('ip -6 route list dev veth99 2001:1234:5:9fff:ff:ff:ff:ff')
|
||||
print(output)
|
||||
self.assertRegex(output, 'via fe80::1034:56ff:fe78:9abd')
|
||||
|
||||
def test_dhcp_client_gateway_onlink_implicit(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
|
||||
'dhcp-client-gateway-onlink-implicit.network')
|
||||
|
|
Loading…
Reference in New Issue