networkd: don't remove route

In case networkd is restarted this prevents a removal of an already existing
route that would be configured using networkd. With the proposed changes the
route will be kept on the interface without removing. This happens only on
physical hosts or VMs since networkd handles interface configuration slightly
different in containers.
This commit is contained in:
Tobias Jungel 2018-11-06 13:28:12 +01:00
parent 30226d2718
commit 7ecf0c3e17
3 changed files with 36 additions and 3 deletions

View File

@ -2634,6 +2634,22 @@ static bool link_is_static_address_configured(Link *link, Address *address) {
return false;
}
static bool link_is_static_route_configured(Link *link, Route *route) {
Route *net_route;
assert(link);
assert(route);
if (!link->network)
return false;
LIST_FOREACH(routes, net_route, link->network->static_routes)
if (route_equal(net_route, route))
return true;
return false;
}
static int link_drop_foreign_config(Link *link) {
Address *address;
Route *route;
@ -2661,9 +2677,15 @@ static int link_drop_foreign_config(Link *link) {
if (route->protocol == RTPROT_KERNEL)
continue;
r = route_remove(route, link, link_route_remove_handler);
if (r < 0)
return r;
if (link_is_static_route_configured(link, route)) {
r = route_add(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL);
if (r < 0)
return r;
} else {
r = route_remove(route, link, link_route_remove_handler);
if (r < 0)
return r;
}
}
return 0;

View File

@ -201,6 +201,16 @@ static const struct hash_ops route_hash_ops = {
.compare = route_compare_func
};
bool route_equal(Route *r1, Route *r2) {
if (r1 == r2)
return true;
if (!r1 || !r2)
return false;
return route_compare_func(r1, r2) == 0;
}
int route_get(Link *link,
int family,
const union in_addr_union *dst,

View File

@ -52,6 +52,7 @@ int route_get(Link *link, int family, const union in_addr_union *dst, unsigned c
int route_add(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
int route_add_foreign(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
void route_update(Route *route, const union in_addr_union *src, unsigned char src_prefixlen, const union in_addr_union *gw, const union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol, unsigned char type);
bool route_equal(Route *r1, Route *r2);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);