1
0
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:
Yu Watanabe 2021-02-04 23:13:08 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent b480543cf0
commit f345918d8d
4 changed files with 119 additions and 40 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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);