network/address: forget address even if we could not remove it

If we could not remove an address, then previously the corresponding
Address object was never removed, as it was freed only when we receive
remove notification from the kernel. So, we might confused that the
address still exists and being removed, and might block reconfiguring
the address.

With this change, even if we fail to remove an address, the
corresponding Address object will be freed.
This commit is contained in:
Yu Watanabe
2024-01-03 04:41:42 +09:00
parent 85a6f300c1
commit 56a995fe8e

View File

@@ -1111,18 +1111,35 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
return 0;
}
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveRequest *rreq) {
int r;
assert(m);
assert(link);
assert(rreq);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
Link *link = ASSERT_PTR(rreq->link);
Address *address = ASSERT_PTR(rreq->userdata);
if (link->state == LINK_STATE_LINGER)
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EADDRNOTAVAIL)
log_link_message_warning_errno(link, m, r, "Could not drop address");
if (r < 0) {
log_link_message_full_errno(link, m,
(r == -EADDRNOTAVAIL || !address->link) ? LOG_DEBUG : LOG_WARNING,
r, "Could not drop address");
if (address->link) {
/* If the address cannot be removed, then assume the address is already removed. */
log_address_debug(address, "Forgetting", link);
Request *req;
if (address_get_request(link, address, &req) >= 0)
address_enter_removed(req->userdata);
(void) address_drop(address);
}
}
return 1;
}
@@ -1149,13 +1166,9 @@ int address_remove(Address *address, Link *link) {
if (r < 0)
return log_link_warning_errno(link, r, "Could not set netlink attributes: %m");
r = netlink_call_async(link->manager->rtnl, NULL, m,
address_remove_handler,
link_netlink_destroy_callback, link);
r = link_remove_request_add(link, address, address, link->manager->rtnl, m, address_remove_handler);
if (r < 0)
return log_link_warning_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
return log_link_warning_errno(link, r, "Could not queue rtnetlink message: %m");
address_enter_removing(address);