]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd:DHCP-client ignore default route if classless static route is set (#6885)
authorSusant Sahani <145210+ssahani@users.noreply.github.com>
Wed, 22 Nov 2017 06:43:55 +0000 (12:13 +0530)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 22 Nov 2017 06:43:55 +0000 (07:43 +0100)
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.

src/network/networkd-dhcp4.c

index bfce641858363c809ddf375c5ecea5ed2e696a12..83b5a39052ec4d897ced6ba3b71b64777b82801c 100644 (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;
 }