diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-02 20:40:33 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-05 11:17:59 +0100 |
commit | 4303e9806befc0c5b8067e45225e5d952f427b3a (patch) | |
tree | cc90776dc9cb69cba645fbb37724e559ad78861b /src/network/networkd-link.c | |
parent | update TODO (diff) | |
download | systemd-4303e9806befc0c5b8067e45225e5d952f427b3a.tar.xz systemd-4303e9806befc0c5b8067e45225e5d952f427b3a.zip |
network/address: also remove address on cancelling request
Otherwise, the address may arrive after we call
link_drop_foreign_address() or so on reconfiguring interface.
Diffstat (limited to 'src/network/networkd-link.c')
-rw-r--r-- | src/network/networkd-link.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 01817737d0..396b2a4d0a 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -931,15 +931,37 @@ static void link_drop_from_master(Link *link) { link_unref(set_remove(master->slaves, link)); } -static void link_drop_requests(Link *link) { +static int link_drop_requests(Link *link) { Request *req; + int ret = 0; assert(link); assert(link->manager); - ORDERED_SET_FOREACH(req, link->manager->request_queue) - if (req->link == link) - request_detach(link->manager, req); + ORDERED_SET_FOREACH(req, link->manager->request_queue) { + if (req->link != link) + continue; + + /* If the request is already called, but its reply is not received, then we need to + * drop the configuration (e.g. address) here. Note, if the configuration is known, + * it will be handled later by link_drop_foreign_addresses() or so. */ + if (req->waiting_reply && link->state != LINK_STATE_LINGER) + switch (req->type) { + case REQUEST_TYPE_ADDRESS: { + Address *address = ASSERT_PTR(req->userdata); + + if (address_get(link, address, NULL) < 0) + RET_GATHER(ret, address_remove(address, link)); + break; + } + default: + ; + } + + request_detach(link->manager, req); + } + + return ret; } static Link *link_drop(Link *link) { @@ -953,7 +975,7 @@ static Link *link_drop(Link *link) { /* Drop all references from other links and manager. Note that async netlink calls may have * references to the link, and they will be dropped when we receive replies. */ - link_drop_requests(link); + (void) link_drop_requests(link); link_free_bound_to_list(link); link_free_bound_by_list(link); @@ -1263,7 +1285,9 @@ int link_reconfigure_impl(Link *link, bool force) { if (r < 0) return r; - link_drop_requests(link); + r = link_drop_requests(link); + if (r < 0) + return r; if (network && !force && network->keep_configuration != KEEP_CONFIGURATION_YES) /* When a new/updated .network file is assigned, first make all configs (addresses, |