network: when Gateway=_dhcp4, set several properties based on lease if they are not explicitly specified

Before this commit, event when Gateway=_dhcp4 or _ra is set, the
route was configured with 'protocol static', and other properties
specified by RouteTable=, RouteMTU=, or etc, were ignored.

This commit makes set the route protocol based on the protocol the
gateway address is obtained, and apply other settings if it is not
explicitly specified in the [Route] section.
This commit is contained in:
Yu Watanabe 2020-10-12 15:52:02 +09:00
parent 5bb80a4603
commit c27abcf4fb
5 changed files with 33 additions and 6 deletions

View File

@ -395,6 +395,14 @@ static int link_set_dhcp_routes(Link *link) {
continue;
rt->gw.in = router[0];
if (!rt->protocol_set)
rt->protocol = RTPROT_DHCP;
if (!rt->priority_set)
rt->priority = link->network->dhcp_route_metric;
if (!rt->table_set)
rt->table = table;
if (rt->mtu == 0)
rt->mtu = link->network->dhcp_route_mtu;
r = dhcp_route_configure(rt, link);
if (r < 0)

View File

@ -461,7 +461,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
union in_addr_union gateway;
uint16_t lifetime;
unsigned preference;
uint32_t mtu;
uint32_t table, mtu;
usec_t time_now;
int r;
@ -504,12 +504,14 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
else if (r < 0)
return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
table = link_get_ipv6_accept_ra_route_table(link);
r = route_new(&route);
if (r < 0)
return log_oom();
route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link);
route->table = table;
route->priority = link->network->dhcp6_route_metric;
route->protocol = RTPROT_RA;
route->pref = preference;
@ -531,6 +533,17 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
continue;
route_gw->gw = gateway;
if (!route_gw->table_set)
route_gw->table = table;
if (!route_gw->priority_set)
route_gw->priority = link->network->dhcp6_route_metric;
if (!route_gw->protocol_set)
route_gw->protocol = RTPROT_RA;
if (!route_gw->pref_set)
route->pref = preference;
route_gw->lifetime = time_now + lifetime * USEC_PER_SEC;
if (route_gw->mtu == 0)
route_gw->mtu = mtu;
r = ndisc_route_configure(route_gw, link, rt);
if (r < 0)

View File

@ -1902,6 +1902,7 @@ int config_parse_route_priority(
return 0;
}
n->priority_set = true;
TAKE_PTR(n);
return 0;
}
@ -2086,6 +2087,7 @@ int config_parse_ipv6_route_preference(
return 0;
}
n->pref_set = true;
TAKE_PTR(n);
return 0;
}

View File

@ -32,20 +32,24 @@ typedef struct Route {
unsigned char dst_prefixlen;
unsigned char src_prefixlen;
unsigned char scope;
bool scope_set;
unsigned char protocol; /* RTPROT_* */
unsigned char type; /* RTN_* */
unsigned char tos;
uint32_t priority; /* note that ip(8) calls this 'metric' */
uint32_t table;
bool table_set;
uint32_t mtu;
uint32_t initcwnd;
uint32_t initrwnd;
unsigned char pref;
unsigned flags;
int gateway_onlink;
bool gateway_from_dhcp_or_ra;
bool scope_set:1;
bool table_set:1;
bool priority_set:1;
bool protocol_set:1;
bool pref_set:1;
bool gateway_from_dhcp_or_ra:1;
union in_addr_union gw;
union in_addr_union dst;

View File

@ -3899,7 +3899,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
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')
self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto dhcp')
def test_dhcp_client_gateway_ipv6(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',