diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index eddeb0d5ef7..8dd89c22a27 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -698,7 +698,7 @@ static int dhcp4_address_ready_callback(Address *address) { return r; /* Reconfigure static routes as kernel may remove some routes when lease expires. */ - r = link_request_set_routes(link); + r = link_set_routes(link); if (r < 0) return r; @@ -755,9 +755,9 @@ static int dhcp4_update_address(Link *link, bool announce) { link_set_state(link, LINK_STATE_CONFIGURING); link->dhcp4_configured = false; - /* address_handler calls link_request_set_routes() and link_request_set_nexthop(). Before they - * are called, the related flags must be cleared. Otherwise, the link becomes configured state - * before routes are configured. */ + /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are called, the + * related flags must be cleared. Otherwise, the link becomes configured state before routes + * are configured. */ link->static_routes_configured = false; link->static_nexthops_configured = false; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 7996e825c29..f0642c9f724 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -342,7 +342,7 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin return 1; } - r = link_request_set_routes(link); + r = link_set_routes(link); if (r < 0) { link_enter_failed(link); return 1; @@ -607,9 +607,9 @@ static int dhcp6_pd_finalize(Link *link) { link->dhcp6_pd_address_configured = true; } else { log_link_debug(link, "Setting DHCPv6 PD addresses"); - /* address_handler calls link_request_set_routes() and link_request_set_nexthop(). - * Before they are called, the related flags must be cleared. Otherwise, the link - * becomes configured state before routes are configured. */ + /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are + * called, the related flags must be cleared. Otherwise, the link becomes configured + * state before routes are configured. */ link->static_routes_configured = false; link->static_nexthops_configured = false; } @@ -952,7 +952,7 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link * return 1; } - r = link_request_set_routes(link); + r = link_set_routes(link); if (r < 0) { link_enter_failed(link); return 1; @@ -1075,9 +1075,9 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) { link->dhcp6_address_configured = true; else { log_link_debug(link, "Setting DHCPv6 addresses"); - /* address_handler calls link_request_set_routes() and link_request_set_nexthop(). - * Before they are called, the related flags must be cleared. Otherwise, the link - * becomes configured state before routes are configured. */ + /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are + * called, the related flags must be cleared. Otherwise, the link becomes configured + * state before routes are configured. */ link->static_routes_configured = false; link->static_nexthops_configured = false; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5c29af2c2d0..0722bc2f662 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -929,89 +929,6 @@ static void link_enter_configured(Link *link) { link_dirty(link); } -static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - int r; - - assert(link); - assert(link->route_messages > 0); - assert(IN_SET(link->state, LINK_STATE_CONFIGURING, - LINK_STATE_FAILED, LINK_STATE_LINGER)); - - 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"); - link_enter_failed(link); - return 1; - } - - if (link->route_messages == 0) { - log_link_debug(link, "Routes set"); - link->static_routes_configured = true; - link_set_nexthop(link); - } - - return 1; -} - -int link_request_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; - Route *rt; - int r; - - assert(link); - assert(link->network); - assert(link->state != _LINK_STATE_INVALID); - - link->static_routes_configured = false; - - if (!link->addresses_ready) - return 0; - - 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; - - r = link_set_routing_policy_rules(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++) - LIST_FOREACH(routes, rt, link->network->static_routes) { - if (rt->gateway_from_dhcp) - continue; - - if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY)) - continue; - - r = route_configure(rt, link, route_handler, NULL); - if (r < 0) - return log_link_warning_errno(link, r, "Could not set routes: %m"); - if (r > 0) - 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); - } - - return 0; -} - void link_check_ready(Link *link) { Address *a; @@ -1161,7 +1078,7 @@ static int static_address_ready_callback(Address *address) { link->addresses_ready = true; - return link_request_set_routes(link); + return link_set_routes(link); } static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { @@ -1328,7 +1245,7 @@ static int link_request_set_addresses(Link *link) { if (link->address_messages == 0) { link->addresses_configured = true; link->addresses_ready = true; - r = link_request_set_routes(link); + r = link_set_routes(link); if (r < 0) return r; } else { diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 1550db8a239..aadbddc910c 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -240,7 +240,6 @@ LinkState link_state_from_string(const char *s) _pure_; uint32_t link_get_vrf_table(Link *link); uint32_t link_get_dhcp_route_table(Link *link); uint32_t link_get_ipv6_accept_ra_route_table(Link *link); -int link_request_set_routes(Link *link); int link_reconfigure(Link *link, bool force); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 68a66649f02..64b27276e08 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -368,7 +368,7 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link * return 1; } - r = link_request_set_routes(link); + r = link_set_routes(link); if (r < 0) { link_enter_failed(link); return 1; @@ -1133,9 +1133,9 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { else { log_link_debug(link, "Setting SLAAC addresses."); - /* address_handler calls link_request_set_routes() and link_request_set_nexthop(). - * Before they are called, the related flags must be cleared. Otherwise, the link - * becomes configured state before routes are configured. */ + /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are + * called, the related flags must be cleared. Otherwise, the link becomes configured + * state before routes are configured. */ link->static_routes_configured = false; link->static_nexthops_configured = false; } diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 2610b24c82a..f4b794f5c30 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -10,7 +10,9 @@ #include "networkd-ipv4ll.h" #include "networkd-manager.h" #include "networkd-ndisc.h" +#include "networkd-nexthop.h" #include "networkd-route.h" +#include "networkd-routing-policy-rule.h" #include "parse-util.h" #include "set.h" #include "socket-netlink.h" @@ -821,6 +823,89 @@ int route_configure( return 1; } +static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(link); + assert(link->route_messages > 0); + assert(IN_SET(link->state, LINK_STATE_CONFIGURING, + LINK_STATE_FAILED, LINK_STATE_LINGER)); + + 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"); + link_enter_failed(link); + return 1; + } + + if (link->route_messages == 0) { + log_link_debug(link, "Routes set"); + link->static_routes_configured = true; + link_set_nexthop(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; + Route *rt; + int r; + + assert(link); + assert(link->network); + assert(link->state != _LINK_STATE_INVALID); + + link->static_routes_configured = false; + + if (!link->addresses_ready) + return 0; + + 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; + + r = link_set_routing_policy_rules(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++) + LIST_FOREACH(routes, rt, link->network->static_routes) { + if (rt->gateway_from_dhcp) + continue; + + if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY)) + continue; + + r = route_configure(rt, link, route_handler, NULL); + if (r < 0) + return log_link_warning_errno(link, r, "Could not set routes: %m"); + if (r > 0) + 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); + } + + return 0; +} + int network_add_ipv4ll_route(Network *network) { _cleanup_(route_free_or_set_invalidp) Route *n = NULL; int r; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 75651fa5122..9b133919041 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -71,6 +71,8 @@ void route_free(Route *route); int route_configure(Route *route, Link *link, link_netlink_message_handler_t callback, Route **ret); int route_remove(Route *route, Link *link, link_netlink_message_handler_t callback); +int link_set_routes(Link *link); + int route_get(Link *link, Route *in, Route **ret); int route_add(Link *link, Route *in, Route **ret); int route_add_foreign(Link *link, Route *in, Route **ret);