]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/dhcp4: accept local subnet routes from DHCP
authorTuetuopay <tuetuopay@me.com>
Fri, 27 Jan 2023 14:10:49 +0000 (15:10 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 31 Jan 2023 23:58:34 +0000 (23:58 +0000)
RFC3442 specifies option 121 (Classless Static Routes) that allow a DHCP
server to push arbitrary routes to a client. It has a Local Subnet
Routes section expliciting the behavior of routes with a null (0.0.0.0)
gateway.

Such routes are to be installed on the interface with a Link scope, to
mark them as directly available on the link without any gateway.

Networkd currently drops those routes, which is against the RFC, as
Linux has proper support for such routes.

Fixes: 7f20627 ("network: dhcp4: ignore gateway in static routes if destination is link-local or in the same network")
src/network/networkd-dhcp4.c

index 1d5e2975a8c5e33bfb0f115937a7368ed0f709fa..d4b49421738da87f7f0fc73757488dd56403159e 100644 (file)
@@ -337,15 +337,18 @@ static int dhcp4_request_route_auto(
                 route->gw = IN_ADDR_NULL;
                 route->prefsrc.in = address;
 
-        } else {
-                if (in4_addr_is_null(gw)) {
-                        log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is not in the assigned network "
-                                       IPV4_ADDRESS_FMT_STR"/%u, but no gateway is specified, ignoring.",
-                                       IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen,
-                                       IPV4_ADDRESS_FMT_VAL(prefix), prefixlen);
-                        return 0;
-                }
+        } else if (in4_addr_is_null(gw)) {
+                log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is not in the assigned network "
+                               IPV4_ADDRESS_FMT_STR"/%u, but no gateway is specified, using 'link' scope.",
+                               IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen,
+                               IPV4_ADDRESS_FMT_VAL(prefix), prefixlen);
 
+                route->scope = RT_SCOPE_LINK;
+                route->gw_family = AF_UNSPEC;
+                route->gw = IN_ADDR_NULL;
+                route->prefsrc.in = address;
+
+        } else {
                 r = dhcp4_request_route_to_gateway(link, gw);
                 if (r < 0)
                         return r;