networkd:DHCP-client ignore default route if classless static route is set (#6885)
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. fixes #5695.
This commit is contained in:
parent
ffb70e4424
commit
5f04a209ea
|
@ -94,13 +94,44 @@ static int link_set_dhcp_routes(Link *link) {
|
|||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
|
||||
|
||||
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
|
||||
if (n == -ENODATA)
|
||||
return 0;
|
||||
if (n < 0)
|
||||
return log_link_warning_errno(link, n, "DHCP error: could not get routes: %m");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_route_free_ Route *route = NULL;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
|
||||
route->family = AF_INET;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
assert_se(sd_dhcp_route_get_gateway(static_routes[i], &route->gw.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->scope = route_scope_from_address(route, &address);
|
||||
|
||||
r = route_configure(route, link, dhcp4_route_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set host route: %m");
|
||||
|
||||
link->dhcp4_messages++;
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
|
||||
if (r == -ENODATA)
|
||||
log_link_info_errno(link, r, "DHCP: No routes received from DHCP server: %m");
|
||||
else if (r < 0)
|
||||
log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
|
||||
|
||||
if (r >= 0) {
|
||||
/* 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 (r >= 0 && link->dhcp4_messages <= 0) {
|
||||
_cleanup_route_free_ Route *route = NULL;
|
||||
_cleanup_route_free_ Route *route_gw = NULL;
|
||||
|
||||
|
@ -148,40 +179,6 @@ static int link_set_dhcp_routes(Link *link) {
|
|||
link->dhcp4_messages++;
|
||||
}
|
||||
|
||||
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
|
||||
if (n == -ENODATA)
|
||||
log_link_info_errno(link, n, "DHCP: No routes received from DHCP server: %m");
|
||||
else if (n < 0)
|
||||
log_link_warning_errno(link, n, "DHCP error: could not get routes: %m");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_route_free_ Route *route = NULL;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
|
||||
route->family = AF_INET;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
assert_se(sd_dhcp_route_get_gateway(static_routes[i], &route->gw.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->scope = route_scope_from_address(route, &address);
|
||||
|
||||
r = route_configure(route, link, dhcp4_route_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set host route: %m");
|
||||
|
||||
link->dhcp4_messages++;
|
||||
}
|
||||
|
||||
if (link->dhcp4_messages == 0) {
|
||||
link->dhcp4_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue