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:
Susant Sahani 2017-11-22 12:13:55 +05:30 committed by Zbigniew Jędrzejewski-Szmek
parent ffb70e4424
commit 5f04a209ea

View file

@ -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;
}