Merge pull request #10597 from toanju/fix-networkd-l3-loss

networkd: don't remove ip address or route
This commit is contained in:
Lennart Poettering 2018-11-06 17:44:24 +03:00 committed by GitHub
commit a0ca258adf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 6 deletions

View file

@ -428,6 +428,7 @@ int address_remove(
sd_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
_cleanup_free_ char *b = NULL;
int r;
assert(address);
@ -437,6 +438,11 @@ int address_remove(
assert(link->manager);
assert(link->manager->rtnl);
if (DEBUG_LOGGING) {
if (in_addr_to_string(address->family, &address->in_addr, &b) >= 0)
log_link_debug(link, "Removing address %s", b);
}
r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR,
link->ifindex, address->family);
if (r < 0)

View file

@ -2618,6 +2618,38 @@ static int link_set_ipv6_mtu(Link *link) {
return 0;
}
static bool link_is_static_address_configured(Link *link, Address *address) {
Address *net_address;
assert(link);
assert(address);
if (!link->network)
return false;
LIST_FOREACH(addresses, net_address, link->network->static_addresses)
if (address_equal(net_address, address))
return true;
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;
@ -2629,9 +2661,15 @@ static int link_drop_foreign_config(Link *link) {
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
continue;
r = address_remove(address, link, link_address_remove_handler);
if (r < 0)
return r;
if (link_is_static_address_configured(link, address)) {
r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Failed to add address: %m");
} else {
r = address_remove(address, link, link_address_remove_handler);
if (r < 0)
return r;
}
}
SET_FOREACH(route, link->routes_foreign, i) {
@ -2639,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);