Merge pull request #10597 from toanju/fix-networkd-l3-loss
networkd: don't remove ip address or route
This commit is contained in:
commit
a0ca258adf
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue