mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
network: configure nexthop before routes that requires gateway
This is a preparation for later commits. When RTA_NH_ID is set to a route, then the corresponding nexthop must be exist.
This commit is contained in:
parent
b480543cf0
commit
f345918d8d
@ -251,9 +251,12 @@ static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||
}
|
||||
|
||||
if (link->nexthop_messages == 0) {
|
||||
log_link_debug(link, "Nexthop set");
|
||||
log_link_debug(link, "Nexthops set");
|
||||
link->static_nexthops_configured = true;
|
||||
link_check_ready(link);
|
||||
/* Now all nexthops are configured. Let's configure remaining routes. */
|
||||
r = link_set_routes_with_gateway(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -307,7 +310,7 @@ static int nexthop_configure(const NextHop *nexthop, Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int link_set_nexthop(Link *link) {
|
||||
int link_set_nexthops(Link *link) {
|
||||
enum {
|
||||
PHASE_ID, /* First phase: Nexthops with ID */
|
||||
PHASE_WITHOUT_ID, /* Second phase: Nexthops without ID */
|
||||
@ -340,13 +343,14 @@ int link_set_nexthop(Link *link) {
|
||||
|
||||
if (link->nexthop_messages == 0) {
|
||||
link->static_nexthops_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting nexthop");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
/* Finaly, configure routes with gateways. */
|
||||
return link_set_routes_with_gateway(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
log_link_debug(link, "Setting nexthops");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
|
@ -33,7 +33,7 @@ NextHop *nexthop_free(NextHop *nexthop);
|
||||
|
||||
void network_drop_invalid_nexthops(Network *network);
|
||||
|
||||
int link_set_nexthop(Link *link);
|
||||
int link_set_nexthops(Link *link);
|
||||
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
|
@ -1193,7 +1193,7 @@ int route_configure(
|
||||
return k;
|
||||
}
|
||||
|
||||
static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int route_handler_with_gateway(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -1206,29 +1206,115 @@ static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route");
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
log_link_debug(link, "Routes set");
|
||||
log_link_debug(link, "Routes with gateway set");
|
||||
link->static_routes_configured = true;
|
||||
link_set_nexthop(link);
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_set_routes(Link *link) {
|
||||
enum {
|
||||
PHASE_NON_GATEWAY, /* First phase: Routes without a gateway */
|
||||
PHASE_GATEWAY, /* Second phase: Routes with a gateway */
|
||||
_PHASE_MAX
|
||||
} phase;
|
||||
static int route_handler_without_gateway(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->route_messages > 0);
|
||||
|
||||
link->route_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route without gateway");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
log_link_debug(link, "Routes set without gateway");
|
||||
/* Now, we can talk to gateways, let's configure nexthops. */
|
||||
r = link_set_nexthops(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool route_has_gateway(const Route *route) {
|
||||
assert(route);
|
||||
|
||||
if (in_addr_is_set(route->gw_family, &route->gw))
|
||||
return true;
|
||||
|
||||
if (!ordered_set_isempty(route->multipath_routes))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int link_set_routes_internal(Link *link, bool with_gateway) {
|
||||
Route *rt;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
HASHMAP_FOREACH(rt, link->network->routes_by_section) {
|
||||
if (rt->gateway_from_dhcp_or_ra)
|
||||
continue;
|
||||
|
||||
if (route_has_gateway(rt) != with_gateway)
|
||||
continue;
|
||||
|
||||
r = route_configure(rt, link, with_gateway ? route_handler_with_gateway : route_handler_without_gateway, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set routes: %m");
|
||||
|
||||
link->route_messages++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_set_routes_with_gateway(Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
||||
* the addresses now, let's not configure the routes either. */
|
||||
return 0;
|
||||
|
||||
/* Finaly, add routes that needs a gateway. */
|
||||
r = link_set_routes_internal(link, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
link->static_routes_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting routes with gateway");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_set_routes(Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(link->state != _LINK_STATE_INVALID);
|
||||
@ -1252,29 +1338,17 @@ int link_set_routes(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
|
||||
for (phase = 0; phase < _PHASE_MAX; phase++)
|
||||
HASHMAP_FOREACH(rt, link->network->routes_by_section) {
|
||||
if (rt->gateway_from_dhcp_or_ra)
|
||||
continue;
|
||||
/* First, add the routes that enable us to talk to gateways. */
|
||||
r = link_set_routes_internal(link, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if ((!in_addr_is_set(rt->gw_family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
|
||||
continue;
|
||||
if (link->route_messages == 0)
|
||||
/* If no route is configured, then configure nexthops. */
|
||||
return link_set_nexthops(link);
|
||||
|
||||
r = route_configure(rt, link, route_handler, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set routes: %m");
|
||||
|
||||
link->route_messages++;
|
||||
}
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
link->static_routes_configured = true;
|
||||
link_set_nexthop(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting routes");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
log_link_debug(link, "Setting routes without gateway");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ int route_configure(const Route *route, Link *link, link_netlink_message_handler
|
||||
int route_remove(const Route *route, Manager *manager, Link *link, link_netlink_message_handler_t callback);
|
||||
|
||||
int link_set_routes(Link *link);
|
||||
int link_set_routes_with_gateway(Link *link);
|
||||
int link_drop_routes(Link *link);
|
||||
int link_drop_foreign_routes(Link *link);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user