mirror of
https://github.com/systemd/systemd.git
synced 2024-10-31 07:51:21 +03:00
network: make manager_find_uplink() uses stored route information
networkd already has all information about routes. It is not necessary to re-read them by using local_gateways(). This also makes manager_find_uplink() take family.
This commit is contained in:
parent
ab486ef4eb
commit
fb3aec45a0
@ -363,7 +363,7 @@ static int dhcp4_server_configure(Link *link) {
|
||||
else {
|
||||
/* Emission is requested, but nothing explicitly configured. Let's find a suitable upling */
|
||||
if (!acquired_uplink) {
|
||||
uplink = manager_find_uplink(link->manager, link);
|
||||
(void) manager_find_uplink(link->manager, AF_INET, link, &uplink);
|
||||
acquired_uplink = true;
|
||||
}
|
||||
|
||||
|
@ -719,43 +719,6 @@ int manager_enumerate(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Link* manager_find_uplink(Manager *m, Link *exclude) {
|
||||
_cleanup_free_ struct local_address *gateways = NULL;
|
||||
int n;
|
||||
|
||||
assert(m);
|
||||
|
||||
/* Looks for a suitable "uplink", via black magic: an
|
||||
* interface that is up and where the default route with the
|
||||
* highest priority points to. */
|
||||
|
||||
n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
|
||||
if (n < 0) {
|
||||
log_warning_errno(n, "Failed to determine list of default gateways: %m");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Link *link;
|
||||
|
||||
link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
|
||||
if (!link) {
|
||||
log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (link == exclude)
|
||||
continue;
|
||||
|
||||
if (link->operstate < LINK_OPERSTATE_ROUTABLE)
|
||||
continue;
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
|
||||
const sd_bus_error *e;
|
||||
int r;
|
||||
|
@ -111,8 +111,6 @@ bool manager_should_reload(Manager *m);
|
||||
|
||||
int manager_enumerate(Manager *m);
|
||||
|
||||
Link* manager_find_uplink(Manager *m, Link *exclude);
|
||||
|
||||
int manager_set_hostname(Manager *m, const char *hostname);
|
||||
int manager_set_timezone(Manager *m, const char *timezone);
|
||||
|
||||
|
@ -646,10 +646,10 @@ static int radv_set_domains(Link *link, Link *uplink) {
|
||||
}
|
||||
|
||||
int radv_emit_dns(Link *link) {
|
||||
Link *uplink;
|
||||
Link *uplink = NULL;
|
||||
int r;
|
||||
|
||||
uplink = manager_find_uplink(link->manager, link);
|
||||
(void) manager_find_uplink(link->manager, AF_INET6, link, &uplink);
|
||||
|
||||
r = radv_set_dns(link, uplink);
|
||||
if (r < 0)
|
||||
|
@ -771,6 +771,65 @@ bool manager_address_is_reachable(Manager *manager, int family, const union in_a
|
||||
return false;
|
||||
}
|
||||
|
||||
static Route *routes_get_default_gateway(Set *routes, int family, Route *gw) {
|
||||
Route *route;
|
||||
|
||||
SET_FOREACH(route, routes) {
|
||||
if (family != AF_UNSPEC && route->family != family)
|
||||
continue;
|
||||
if (route->dst_prefixlen != 0)
|
||||
continue;
|
||||
if (route->src_prefixlen != 0)
|
||||
continue;
|
||||
if (route->table != RT_TABLE_MAIN)
|
||||
continue;
|
||||
if (route->type != RTN_UNICAST)
|
||||
continue;
|
||||
if (route->scope != RT_SCOPE_UNIVERSE)
|
||||
continue;
|
||||
if (!in_addr_is_set(route->gw_family, &route->gw))
|
||||
continue;
|
||||
if (gw) {
|
||||
if (route->gw_weight > gw->gw_weight)
|
||||
continue;
|
||||
if (route->priority >= gw->priority)
|
||||
continue;
|
||||
}
|
||||
gw = route;
|
||||
}
|
||||
|
||||
return gw;
|
||||
}
|
||||
|
||||
int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret) {
|
||||
Route *gw = NULL;
|
||||
Link *link;
|
||||
|
||||
assert(m);
|
||||
assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
|
||||
|
||||
/* Looks for a suitable "uplink", via black magic: an interface that is up and where the
|
||||
* default route with the highest priority points to. */
|
||||
|
||||
HASHMAP_FOREACH(link, m->links) {
|
||||
if (link == exclude)
|
||||
continue;
|
||||
|
||||
if (link->state != LINK_STATE_CONFIGURED)
|
||||
continue;
|
||||
|
||||
gw = routes_get_default_gateway(link->routes, family, gw);
|
||||
gw = routes_get_default_gateway(link->routes_foreign, family, gw);
|
||||
}
|
||||
|
||||
if (!gw)
|
||||
return -ENOENT;
|
||||
|
||||
assert(gw->link);
|
||||
*ret = gw->link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void log_route_debug(const Route *route, const char *str, const Link *link, const Manager *manager) {
|
||||
_cleanup_free_ char *dst = NULL, *src = NULL, *gw_alloc = NULL, *prefsrc = NULL,
|
||||
*table = NULL, *scope = NULL, *proto = NULL;
|
||||
|
@ -78,6 +78,7 @@ int route_remove(const Route *route, Manager *manager, Link *link);
|
||||
|
||||
int link_has_route(Link *link, const Route *route);
|
||||
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address);
|
||||
int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
|
||||
|
||||
int link_drop_routes(Link *link);
|
||||
int link_drop_foreign_routes(Link *link);
|
||||
|
Loading…
Reference in New Issue
Block a user