]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not set nexthop ID, gateway, and multipath routes simultaneously 19458/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 29 Apr 2021 11:58:10 +0000 (20:58 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 29 Apr 2021 13:54:40 +0000 (22:54 +0900)
See kernel's rtm_to_fib_config() in net/ipv4/fib_frontend.c and
rtm_to_fib6_config() in net/ipv6/route.c.

Note that if both gateway and multipath routes are specified, then
kernel ignores gateway. So, strictly speaking, setting both gateway and
multipath routes is allowed by kernel. But such situation is mostly
user's misconfiguration. Let's refuse it.

Note that the conditions newly added in route_configure() are redundant,
as all static configurations are already verified in
route_section_verify(), and dynamic configurations do not set
nexthop_id or multipath routes. Just for safety.

src/network/networkd-route.c

index c1e5f6b4b8240d6dae0f8569ee4a684d1a22ec51..070131f4af7378e936ae0b5ffd01cfb00b364356 100644 (file)
@@ -645,7 +645,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
 
         /* link may be NULL */
 
-        if (in_addr_is_set(route->gw_family, &route->gw)) {
+        if (in_addr_is_set(route->gw_family, &route->gw) && route->nexthop_id == 0) {
                 if (route->gw_family == route->family) {
                         r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
                         if (r < 0)
@@ -1100,8 +1100,8 @@ int route_configure(
                 Route **ret) {
 
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
-        int r, k = 0;
         Route *nr;
+        int r, k;
 
         assert(link);
         assert(link->manager);
@@ -1188,19 +1188,22 @@ int route_configure(
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
 
-        r = append_nexthops(route, req);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
-
-        if (ordered_set_isempty(route->multipath_routes)) {
+        if (route->nexthop_id != 0 ||
+            in_addr_is_set(route->gw_family, &route->gw) ||
+            ordered_set_isempty(route->multipath_routes)) {
                 k = route_add_and_setup_timer(link, route, NULL, &nr);
                 if (k < 0)
                         return k;
         } else {
                 MultipathRoute *m;
 
+                r = append_nexthops(route, req);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
+
                 assert(!ret);
 
+                k = 0;
                 ORDERED_SET_FOREACH(m, route->multipath_routes) {
                         r = route_add_and_setup_timer(link, route, m, NULL);
                         if (r < 0)
@@ -2766,8 +2769,17 @@ static int route_section_verify(Route *route, Network *network) {
                                                          route->section->filename, route->section->line);
         }
 
+        if ((route->gateway_from_dhcp_or_ra ||
+             in_addr_is_set(route->gw_family, &route->gw)) &&
+            !ordered_set_isempty(route->multipath_routes))
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: Gateway= cannot be specified with MultiPathRoute=. "
+                                         "Ignoring [Route] section from line %u.",
+                                         route->section->filename, route->section->line);
+
         if (route->nexthop_id > 0 &&
-            (in_addr_is_set(route->gw_family, &route->gw) ||
+            (route->gateway_from_dhcp_or_ra ||
+             in_addr_is_set(route->gw_family, &route->gw) ||
              !ordered_set_isempty(route->multipath_routes)))
                 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
                                          "%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. "