From: Yu Watanabe Date: Tue, 2 Jan 2024 19:41:42 +0000 (+0900) Subject: network/address: forget address even if we could not remove it X-Git-Tag: v256-rc1~1164^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56a995fe8e50b2432ff930ed0431cc70adbe492d;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index e54c1223614..4c3393645e7 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -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);