summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/networkd-route-nexthop.c86
-rw-r--r--src/network/networkd-route-nexthop.h6
-rw-r--r--src/network/networkd-route.c60
3 files changed, 93 insertions, 59 deletions
diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c
index 4c46794a0f..e20c0eb72b 100644
--- a/src/network/networkd-route-nexthop.c
+++ b/src/network/networkd-route-nexthop.c
@@ -6,12 +6,98 @@
#include "extract-word.h"
#include "netlink-util.h"
#include "networkd-network.h"
+#include "networkd-nexthop.h"
#include "networkd-route.h"
#include "networkd-route-nexthop.h"
#include "networkd-route-util.h"
#include "parse-util.h"
#include "string-util.h"
+int multipath_route_get_link(Manager *manager, const MultipathRoute *m, Link **ret) {
+ int r;
+
+ assert(manager);
+ assert(m);
+
+ if (m->ifname) {
+ r = link_get_by_name(manager, m->ifname, ret);
+ return r < 0 ? r : 1;
+
+ } else if (m->ifindex > 0) { /* Always ignore ifindex if ifname is set. */
+ r = link_get_by_index(manager, m->ifindex, ret);
+ return r < 0 ? r : 1;
+ }
+
+ if (ret)
+ *ret = NULL;
+ return 0;
+}
+
+static bool multipath_route_is_ready_to_configure(MultipathRoute *m, Link *link, bool onlink) {
+ union in_addr_union a = m->gateway.address;
+ Link *l = NULL;
+ int r;
+
+ assert(m);
+ assert(link);
+
+ r = multipath_route_get_link(link->manager, m, &l);
+ if (r < 0)
+ return false;
+ if (r > 0)
+ link = l;
+
+ if (!link_is_ready_to_configure(link, /* allow_unmanaged = */ true))
+ return false;
+
+ /* If the interface is not managed by us, we request that the interface has carrier.
+ * That is, ConfigureWithoutCarrier=no is the default even for unamanaged interfaces. */
+ if (!link->network && !link_has_carrier(link))
+ return false;
+
+ m->ifindex = link->ifindex;
+ return gateway_is_ready(link, onlink, m->gateway.family, &a);
+}
+
+int route_nexthops_is_ready_to_configure(const Route *route, Link *link) {
+ int r;
+
+ assert(route);
+ assert(link);
+
+ Manager *manager = ASSERT_PTR(link->manager);
+
+ if (route->nexthop_id != 0) {
+ struct nexthop_grp *nhg;
+ NextHop *nh;
+
+ r = nexthop_is_ready(manager, route->nexthop_id, &nh);
+ if (r <= 0)
+ return r;
+
+ HASHMAP_FOREACH(nhg, nh->group) {
+ r = nexthop_is_ready(manager, nhg->id, NULL);
+ if (r <= 0)
+ return r;
+ }
+
+ return true;
+ }
+
+ if (route_type_is_reject(route))
+ return true;
+
+ if (ordered_set_isempty(route->multipath_routes))
+ return gateway_is_ready(link, FLAGS_SET(route->flags, RTNH_F_ONLINK), route->gw_family, &route->gw);
+
+ MultipathRoute *m;
+ ORDERED_SET_FOREACH(m, route->multipath_routes)
+ if (!multipath_route_is_ready_to_configure(m, link, FLAGS_SET(route->flags, RTNH_F_ONLINK)))
+ return false;
+
+ return true;
+}
+
int route_nexthops_to_string(const Route *route, char **ret) {
_cleanup_free_ char *buf = NULL;
int r;
diff --git a/src/network/networkd-route-nexthop.h b/src/network/networkd-route-nexthop.h
index 982b20551a..7a0b0adce2 100644
--- a/src/network/networkd-route-nexthop.h
+++ b/src/network/networkd-route-nexthop.h
@@ -3,8 +3,14 @@
#include "conf-parser.h"
+typedef struct Link Link;
+typedef struct Manager Manager;
+typedef struct MultipathRoute MultipathRoute;
typedef struct Route Route;
+int multipath_route_get_link(Manager *manager, const MultipathRoute *m, Link **ret);
+int route_nexthops_is_ready_to_configure(const Route *route, Link *link);
+
int route_nexthops_to_string(const Route *route, char **ret);
int route_nexthops_set_netlink_message(Link *link, const Route *route, sd_netlink_message *message);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 4186a74e39..a71ee4375a 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -348,26 +348,6 @@ static void route_apply_multipath_route(Route *route, const MultipathRoute *m) {
route->gw_weight = m->weight;
}
-static int multipath_route_get_link(Manager *manager, const MultipathRoute *m, Link **ret) {
- int r;
-
- assert(manager);
- assert(m);
-
- if (m->ifname) {
- r = link_get_by_name(manager, m->ifname, ret);
- return r < 0 ? r : 1;
-
- } else if (m->ifindex > 0) { /* Always ignore ifindex if ifname is set. */
- r = link_get_by_index(manager, m->ifindex, ret);
- return r < 0 ? r : 1;
- }
-
- if (ret)
- *ret = NULL;
- return 0;
-}
-
typedef struct ConvertedRoutes {
size_t n;
Route **routes;
@@ -1064,51 +1044,13 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
if (set_size(link->routes) >= routes_max())
return false;
- if (route->nexthop_id > 0) {
- struct nexthop_grp *nhg;
- NextHop *nh;
-
- r = nexthop_is_ready(link->manager, route->nexthop_id, &nh);
- if (r <= 0)
- return r;
-
- HASHMAP_FOREACH(nhg, nh->group) {
- r = nexthop_is_ready(link->manager, nhg->id, NULL);
- if (r <= 0)
- return r;
- }
- }
-
if (in_addr_is_set(route->family, &route->prefsrc) > 0) {
r = manager_has_address(link->manager, route->family, &route->prefsrc);
if (r <= 0)
return r;
}
- if (!gateway_is_ready(link, FLAGS_SET(route->flags, RTNH_F_ONLINK), route->gw_family, &route->gw))
- return false;
-
- MultipathRoute *m;
- ORDERED_SET_FOREACH(m, route->multipath_routes) {
- union in_addr_union a = m->gateway.address;
- Link *l = NULL;
-
- r = multipath_route_get_link(link->manager, m, &l);
- if (r < 0)
- return false;
- if (r > 0) {
- if (!link_is_ready_to_configure(l, /* allow_unmanaged = */ true) ||
- !link_has_carrier(l))
- return false;
-
- m->ifindex = l->ifindex;
- }
-
- if (!gateway_is_ready(l ?: link, FLAGS_SET(route->flags, RTNH_F_ONLINK), m->gateway.family, &a))
- return false;
- }
-
- return true;
+ return route_nexthops_is_ready_to_configure(route, link);
}
static int route_process_request(Request *req, Link *link, Route *route) {