diff options
Diffstat (limited to '')
-rw-r--r-- | src/network/networkd-address.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 0b7fbec28b..bc5bfb8e83 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1129,6 +1129,23 @@ void log_address_debug(const Address *address, const char *str, const Link *link address->family == AF_INET ? strna(address->label) : ""); } +static void address_forget(Link *link, Address *address, bool removed_by_us, const char *msg) { + assert(link); + assert(address); + assert(msg); + + Request *req; + if (address_get_request(link, address, &req) >= 0) + address_enter_removed(req->userdata); + + if (!address->link && address_get(link, address, &address) < 0) + return; + + address_enter_removed(address); + log_address_debug(address, msg, link); + (void) address_drop(address, removed_by_us); +} + static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) { uint32_t flags; int r; @@ -1181,16 +1198,8 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov (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, /* removed_by_us = */ true); - } + /* If the address cannot be removed, then assume the address is already removed. */ + address_forget(link, address, /* removed_by_us = */ true, "Forgetting"); } return 1; @@ -1775,14 +1784,7 @@ int link_request_static_addresses(Link *link) { } int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { - _cleanup_(address_unrefp) Address *tmp = NULL; - struct ifa_cacheinfo cinfo; - Link *link; - uint16_t type; - Address *address = NULL; - Request *req = NULL; - bool is_new = false, update_dhcp4; - int ifindex, r; + int r; assert(rtnl); assert(message); @@ -1796,6 +1798,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, return 0; } + uint16_t type; r = sd_netlink_message_get_type(message, &type); if (r < 0) { log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); @@ -1805,6 +1808,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, return 0; } + int ifindex; r = sd_rtnl_message_addr_get_ifindex(message, &ifindex); if (r < 0) { log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m"); @@ -1814,6 +1818,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, return 0; } + Link *link; r = link_get_by_index(m, ifindex, &link); if (r < 0) { /* when enumerating we might be out of sync, but we will get the address again, so just @@ -1823,6 +1828,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, return 0; } + _cleanup_(address_unrefp) Address *tmp = NULL; r = address_new(&tmp); if (r < 0) return log_oom(); @@ -1890,28 +1896,22 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, assert_not_reached(); } - update_dhcp4 = tmp->family == AF_INET6; - - /* Then, find the managed Address and Request objects corresponding to the received address. */ + /* Then, find the managed Address object corresponding to the received address. */ + Address *address = NULL; (void) address_get(link, tmp, &address); - (void) address_get_request(link, tmp, &req); if (type == RTM_DELADDR) { - if (address) { - bool removed_by_us = FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING); - - address_enter_removed(address); - log_address_debug(address, "Forgetting removed", link); - (void) address_drop(address, removed_by_us); - } else + if (address) + address_forget(link, address, + /* removed_by_us = */ FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING), + "Forgetting removed"); + else log_address_debug(tmp, "Kernel removed unknown", link); - if (req) - address_enter_removed(req->userdata); - goto finalize; } + bool is_new = false; if (!address) { /* If we did not know the address, then save it. */ r = address_attach(link, tmp); @@ -1931,6 +1931,8 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, } /* Also update information that cannot be obtained through netlink notification. */ + Request *req = NULL; + (void) address_get_request(link, tmp, &req); if (req && req->waiting_reply) { Address *a = ASSERT_PTR(req->userdata); @@ -1978,6 +1980,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, } else if (r < 0) log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m"); + struct ifa_cacheinfo cinfo; r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo); if (r >= 0) address_set_lifetime(m, address, &cinfo); @@ -2000,7 +2003,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, link_enter_failed(link); finalize: - if (update_dhcp4) { + if (tmp->family == AF_INET6) { r = dhcp4_update_ipv6_connectivity(link); if (r < 0) { log_link_warning_errno(link, r, "Failed to notify IPv6 connectivity to DHCPv4 client: %m"); |