summaryrefslogtreecommitdiff
path: root/src/network/networkd-address.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-address.c')
-rw-r--r--src/network/networkd-address.c531
1 files changed, 230 insertions, 301 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index a885697969..4dd4f3691d 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -9,10 +9,12 @@
#include "netlink-util.h"
#include "networkd-address-pool.h"
#include "networkd-address.h"
+#include "networkd-dhcp-server.h"
#include "networkd-ipv4acd.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-queue.h"
+#include "networkd-route.h"
#include "parse-util.h"
#include "string-util.h"
#include "strv.h"
@@ -131,7 +133,7 @@ static int address_new_static(Network *network, const char *filename, unsigned s
address->network = network;
address->section = TAKE_PTR(n);
- address->is_static = true;
+ address->source = NETWORK_CONFIG_SOURCE_STATIC;
r = ordered_hashmap_ensure_put(&network->addresses_by_section, &network_config_hash_ops, address->section, address);
if (r < 0)
@@ -151,23 +153,7 @@ Address *address_free(Address *address) {
}
if (address->link) {
- NDiscAddress *n;
-
set_remove(address->link->addresses, address);
- set_remove(address->link->addresses_foreign, address);
- set_remove(address->link->addresses_ipv4acd, address);
- set_remove(address->link->static_addresses, address);
- if (address->link->dhcp_address == address)
- address->link->dhcp_address = NULL;
- if (address->link->dhcp_address_old == address)
- address->link->dhcp_address_old = NULL;
- set_remove(address->link->dhcp6_addresses, address);
- set_remove(address->link->dhcp6_addresses_old, address);
- set_remove(address->link->dhcp6_pd_addresses, address);
- set_remove(address->link->dhcp6_pd_addresses_old, address);
- SET_FOREACH(n, address->link->ndisc_addresses)
- if (address_equal(n->address, address))
- free(set_remove(address->link->ndisc_addresses, n));
if (address->family == AF_INET6 &&
in6_addr_equal(&address->in_addr.in6, &address->link->ipv6ll_address))
@@ -181,6 +167,41 @@ Address *address_free(Address *address) {
return mfree(address);
}
+bool address_is_ready(const Address *a) {
+ assert(a);
+
+ if (FLAGS_SET(a->flags, IFA_F_TENTATIVE))
+ return false;
+
+ if (FLAGS_SET(a->state, NETWORK_CONFIG_STATE_REMOVING))
+ return false;
+
+ if (FLAGS_SET(a->state, NETWORK_CONFIG_STATE_PROBING))
+ return false;
+
+ if (!FLAGS_SET(a->state, NETWORK_CONFIG_STATE_CONFIGURED))
+ return false;
+
+ return true;
+}
+
+void link_mark_addresses(Link *link, NetworkConfigSource source, const struct in6_addr *router) {
+ Address *a;
+
+ assert(link);
+
+ SET_FOREACH(a, link->addresses) {
+ if (a->source != source)
+ continue;
+
+ if (source == NETWORK_CONFIG_SOURCE_NDISC &&
+ router && !in6_addr_equal(router, &a->provider.in6))
+ continue;
+
+ address_mark(a);
+ }
+}
+
static bool address_may_have_broadcast(const Address *a) {
assert(a);
@@ -371,67 +392,19 @@ static int address_set_masquerade(Address *address, bool add) {
return 0;
}
-static int address_add_internal(Link *link, Set **addresses, const Address *in, Address **ret) {
- _cleanup_(address_freep) Address *address = NULL;
+static int address_add(Link *link, Address *address) {
int r;
assert(link);
- assert(addresses);
- assert(in);
-
- r = address_dup(in, &address);
- if (r < 0)
- return r;
-
- /* Consider address tentative until we get the real flags from the kernel */
- address->flags |= IFA_F_TENTATIVE;
+ assert(address);
- r = set_ensure_put(addresses, &address_hash_ops, address);
+ r = set_ensure_put(&link->addresses, &address_hash_ops, address);
if (r < 0)
return r;
if (r == 0)
return -EEXIST;
address->link = link;
-
- if (ret)
- *ret = address;
- TAKE_PTR(address);
- return 0;
-}
-
-static int address_add_foreign(Link *link, const Address *in, Address **ret) {
- return address_add_internal(link, &link->addresses_foreign, in, ret);
-}
-
-static int address_add(Link *link, const Address *in, Address **ret) {
- Address *address;
- int r;
-
- assert(link);
- assert(in);
-
- r = address_get(link, in, &address);
- if (r == -ENOENT) {
- /* Address does not exist, create a new one */
- r = address_add_internal(link, &link->addresses, in, &address);
- if (r < 0)
- return r;
- } else if (r == 0) {
- /* Take over a foreign address */
- r = set_ensure_put(&link->addresses, &address_hash_ops, address);
- if (r < 0)
- return r;
-
- set_remove(link->addresses_foreign, address);
- } else if (r == 1) {
- /* Already exists, do nothing */
- ;
- } else
- return r;
-
- if (ret)
- *ret = address;
return 0;
}
@@ -441,13 +414,13 @@ static int address_update(Address *address, const Address *src) {
assert(address);
assert(address->link);
- assert(src);
link = address->link;
-
- address->flags = src->flags;
- address->scope = src->scope;
- address->cinfo = src->cinfo;
+ if (src) {
+ address->flags = src->flags;
+ address->scope = src->scope;
+ address->cinfo = src->cinfo;
+ }
if (address_is_ready(address) &&
address->family == AF_INET6 &&
@@ -484,8 +457,8 @@ static int address_drop(Address *address) {
bool ready;
int r;
- if (!address)
- return 0;
+ assert(address);
+ assert(address->link);
ready = address_is_ready(address);
link = address->link;
@@ -494,7 +467,8 @@ static int address_drop(Address *address) {
if (r < 0)
log_link_warning_errno(link, r, "Failed to disable IP masquerading, ignoring: %m");
- address_free(address);
+ if (address->state == 0)
+ address_free(address);
link_update_operstate(link, true);
@@ -511,20 +485,12 @@ int address_get(Link *link, const Address *in, Address **ret) {
assert(in);
existing = set_get(link->addresses, in);
- if (existing) {
- if (ret)
- *ret = existing;
- return 1;
- }
-
- existing = set_get(link->addresses_foreign, in);
- if (existing) {
- if (ret)
- *ret = existing;
- return 0;
- }
+ if (!existing)
+ return -ENOENT;
- return -ENOENT;
+ if (ret)
+ *ret = existing;
+ return 0;
}
int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret) {
@@ -546,27 +512,6 @@ int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **
return address_get(link, a, ret);
}
-static int addresses_get_ipv4_address(Set *addresses, const struct in_addr *address, Address **ret) {
- Address *a;
-
- assert(address);
-
- SET_FOREACH(a, addresses) {
- if (a->family != AF_INET)
- continue;
-
- if (!in4_addr_equal(&a->in_addr.in, address))
- continue;
-
- if (ret)
- *ret = a;
-
- return 0;
- }
-
- return -ENOENT;
-}
-
int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret) {
int r;
@@ -587,11 +532,24 @@ int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned ch
a->prefixlen = prefixlen;
return address_get(link, a, ret);
- }
+ } else {
+ Address *a;
- if (addresses_get_ipv4_address(link->addresses, address, ret) >= 0)
- return 0;
- return addresses_get_ipv4_address(link->addresses_foreign, address, ret);
+ SET_FOREACH(a, link->addresses) {
+ if (a->family != AF_INET)
+ continue;
+
+ if (!in4_addr_equal(&a->in_addr.in, address))
+ continue;
+
+ if (ret)
+ *ret = a;
+
+ return 0;
+ }
+
+ return -ENOENT;
+ }
}
int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready) {
@@ -606,7 +564,7 @@ int manager_has_address(Manager *manager, int family, const union in_addr_union
if (family == AF_INET) {
HASHMAP_FOREACH(link, manager->links_by_index)
if (link_get_ipv4_address(link, &address->in, 0, &a) >= 0)
- return !check_ready || address_is_ready(a);
+ return check_ready ? address_is_ready(a) : address_exists(a);
} else {
_cleanup_(address_freep) Address *tmp = NULL;
@@ -619,7 +577,7 @@ int manager_has_address(Manager *manager, int family, const union in_addr_union
HASHMAP_FOREACH(link, manager->links_by_index)
if (address_get(link, tmp, &a) >= 0)
- return !check_ready || address_is_ready(a);
+ return check_ready ? address_is_ready(a) : address_exists(a);
}
return false;
@@ -639,7 +597,7 @@ const char* format_lifetime(char *buf, size_t l, uint32_t lifetime) {
}
static void log_address_debug(const Address *address, const char *str, const Link *link) {
- _cleanup_free_ char *addr = NULL, *peer = NULL, *flags_str = NULL;
+ _cleanup_free_ char *state = NULL, *addr = NULL, *peer = NULL, *flags_str = NULL;
assert(address);
assert(str);
@@ -648,14 +606,16 @@ static void log_address_debug(const Address *address, const char *str, const Lin
if (!DEBUG_LOGGING)
return;
+ (void) network_config_state_to_string_alloc(address->state, &state);
(void) in_addr_to_string(address->family, &address->in_addr, &addr);
if (in_addr_is_set(address->family, &address->in_addr_peer))
(void) in_addr_to_string(address->family, &address->in_addr_peer, &peer);
(void) address_flags_to_string_alloc(address->flags, address->family, &flags_str);
- log_link_debug(link, "%s address: %s%s%s/%u (valid %s, preferred %s), flags: %s",
- str, strnull(addr), peer ? " peer " : "", strempty(peer), address->prefixlen,
+ log_link_debug(link, "%s %s address (%s): %s%s%s/%u (valid %s, preferred %s), flags: %s",
+ str, strna(network_config_source_to_string(address->source)), strna(state),
+ strnull(addr), peer ? " peer " : "", strempty(peer), address->prefixlen,
FORMAT_LIFETIME(address->cinfo.ifa_valid),
FORMAT_LIFETIME(address->cinfo.ifa_prefered),
strna(flags_str));
@@ -698,12 +658,8 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
- assert(rtnl);
assert(m);
assert(link);
- assert(link->address_remove_messages > 0);
-
- link->address_remove_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
@@ -715,16 +671,19 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
return 1;
}
-int address_remove(const Address *address, Link *link) {
+int address_remove(Address *address) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ Link *link;
int r;
assert(address);
assert(IN_SET(address->family, AF_INET, AF_INET6));
- assert(link);
- assert(link->ifindex > 0);
- assert(link->manager);
- assert(link->manager->rtnl);
+ assert(address->link);
+ assert(address->link->ifindex > 0);
+ assert(address->link->manager);
+ assert(address->link->manager->rtnl);
+
+ link = address->link;
log_address_debug(address, "Removing", link);
@@ -744,27 +703,11 @@ int address_remove(const Address *address, Link *link) {
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
- link->address_remove_messages++;
+ address_enter_removing(address);
return 0;
}
-static bool link_is_static_address_configured(const Link *link, const Address *address) {
- Address *net_address;
-
- assert(link);
- assert(address);
-
- if (!link->network)
- return false;
-
- ORDERED_HASHMAP_FOREACH(net_address, link->network->addresses_by_section)
- if (address_equal(net_address, address))
- return true;
-
- return false;
-}
-
bool link_address_is_dynamic(const Link *link, const Address *address) {
Route *route;
@@ -777,7 +720,10 @@ bool link_address_is_dynamic(const Link *link, const Address *address) {
/* Even when the address is leased from a DHCP server, networkd assign the address
* without lifetime when KeepConfiguration=dhcp. So, let's check that we have
* corresponding routes with RTPROT_DHCP. */
- SET_FOREACH(route, link->routes_foreign) {
+ SET_FOREACH(route, link->routes) {
+ if (route->source != NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+
if (route->protocol != RTPROT_DHCP)
continue;
@@ -821,6 +767,7 @@ int link_drop_ipv6ll_addresses(Link *link) {
_cleanup_(address_freep) Address *a = NULL;
unsigned char flags, prefixlen;
struct in6_addr address;
+ Address *existing;
int ifindex;
/* NETLINK_GET_STRICT_CHK socket option is supported since kernel 4.20. To support
@@ -866,7 +813,15 @@ int link_drop_ipv6ll_addresses(Link *link) {
a->prefixlen = prefixlen;
a->flags = flags;
- r = address_remove(a, link);
+ if (address_get(link, a, &existing) < 0) {
+ r = address_add(link, a);
+ if (r < 0)
+ return r;
+
+ existing = TAKE_PTR(a);
+ }
+
+ r = address_remove(existing);
if (r < 0)
return r;
}
@@ -879,63 +834,80 @@ int link_drop_foreign_addresses(Link *link) {
int k, r = 0;
assert(link);
+ assert(link->network);
- SET_FOREACH(address, link->addresses_foreign) {
+ /* First, mark all addresses. */
+ SET_FOREACH(address, link->addresses) {
/* We consider IPv6LL addresses to be managed by the kernel, or dropped in link_drop_ipv6ll_addresses() */
if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6))
continue;
+ /* Ignore addresses we configured. */
+ if (address->source != NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+
+ /* Ignore addresses not assigned yet or already removing. */
+ if (!address_exists(address))
+ continue;
+
if (link_address_is_dynamic(link, address)) {
if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
continue;
} else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
continue;
- if (link_is_static_address_configured(link, address)) {
- k = address_add(link, address, NULL);
- if (k < 0) {
- log_link_error_errno(link, k, "Failed to add address: %m");
- if (r >= 0)
- r = k;
- }
- } else {
- k = address_remove(address, link);
- if (k < 0 && r >= 0)
- r = k;
- }
+ address_mark(address);
+ }
+
+ /* Then, unmark requested addresses. */
+ ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section) {
+ Address *existing;
+
+ if (address_get(link, address, &existing) >= 0)
+ address_unmark(existing);
+ }
+
+ /* Finally, remove all marked addresses. */
+ SET_FOREACH(address, link->addresses) {
+ if (!address_is_marked(address))
+ continue;
+
+ k = address_remove(address);
+ if (k < 0 && r >= 0)
+ r = k;
}
return r;
}
int link_drop_addresses(Link *link) {
- Address *address, *pool_address;
+ Address *address;
int k, r = 0;
assert(link);
SET_FOREACH(address, link->addresses) {
+ /* Ignore addresses not assigned yet or already removing. */
+ if (!address_exists(address))
+ continue;
+
/* We consider IPv6LL addresses to be managed by the kernel, or dropped in link_drop_ipv6ll_addresses() */
if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6))
continue;
- k = address_remove(address, link);
+ k = address_remove(address);
if (k < 0 && r >= 0) {
r = k;
continue;
}
-
- SET_FOREACH(pool_address, link->pool_addresses)
- if (address_equal(address, pool_address))
- address_free(set_remove(link->pool_addresses, pool_address));
}
return r;
}
static int address_acquire(Link *link, const Address *original, Address **ret) {
- union in_addr_union in_addr = IN_ADDR_NULL;
_cleanup_(address_freep) Address *na = NULL;
+ union in_addr_union in_addr;
int r;
assert(link);
@@ -969,12 +941,6 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
na->in_addr = in_addr;
address_set_broadcast(na);
- r = set_ensure_put(&link->pool_addresses, &address_hash_ops, na);
- if (r < 0)
- return r;
- if (r == 0)
- return -EEXIST;
-
*ret = TAKE_PTR(na);
return 1;
}
@@ -1063,6 +1029,25 @@ static int address_configure(
return 0;
}
+void address_cancel_request(Address *address) {
+ Request req;
+
+ assert(address);
+ assert(address->link);
+
+ if (!address_is_requesting(address))
+ return;
+
+ req = (Request) {
+ .link = address->link,
+ .type = REQUEST_TYPE_ADDRESS,
+ .address = address,
+ };
+
+ request_drop(ordered_set_get(address->link->manager->request_queue, &req));
+ address_cancel_requesting(address);
+}
+
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
@@ -1084,25 +1069,6 @@ static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
return 1;
}
-static int static_address_after_configure(Request *req, void *object) {
- Address *address = object;
- Link *link;
- int r;
-
- assert(req);
- assert(req->link);
- assert(req->type == REQUEST_TYPE_ADDRESS);
- assert(address);
-
- link = req->link;
-
- r = set_ensure_put(&link->static_addresses, &address_hash_ops, address);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to store static address: %m");
-
- return 0;
-}
-
int link_request_address(
Link *link,
Address *address,
@@ -1111,50 +1077,72 @@ int link_request_address(
link_netlink_message_handler_t netlink_handler,
Request **ret) {
- Address *acquired;
+ Address *acquired, *existing;
int r;
assert(link);
assert(address);
+ assert(address->source != NETWORK_CONFIG_SOURCE_FOREIGN);
r = address_acquire(link, address, &acquired);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to acquire an address from pool: %m");
if (r > 0) {
- if (consume_object) {
+ if (consume_object)
address_free(address);
- consume_object = false; /* address from pool is already managed by Link. */
- }
+
address = acquired;
+ consume_object = true;
+ }
+
+ if (address_get(link, address, &existing) < 0) {
+ _cleanup_(address_freep) Address *tmp = NULL;
+
+ r = address_dup(address, &tmp);
+ if (r < 0)
+ return r;
+
+ /* Consider address tentative until we get the real flags from the kernel */
+ tmp->flags |= IFA_F_TENTATIVE;
+
+ r = address_add(link, tmp);
+ if (r < 0)
+ return r;
+
+ existing = TAKE_PTR(tmp);
+ } else {
+ existing->source = address->source;
+ existing->provider = address->provider;
}
+ r = ipv4acd_configure(existing);
+ if (r < 0)
+ return r;
+
log_address_debug(address, "Requesting", link);
r = link_queue_request(link, REQUEST_TYPE_ADDRESS, address, consume_object,
message_counter, netlink_handler, ret);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request address: %m");
- return r;
+ if (r == 0)
+ return 0;
+
+ address_enter_requesting(existing);
+
+ return 1;
}
int link_request_static_address(Link *link, Address *address, bool consume) {
- Request *req;
- int r;
-
assert(link);
assert(address);
+ assert(address->source == NETWORK_CONFIG_SOURCE_STATIC);
- r = link_request_address(link, address, consume, &link->static_address_messages,
- static_address_handler, &req);
- if (r <= 0)
- return r;
-
- req->after_configure = static_address_after_configure;
- return 0;
+ return link_request_address(link, address, consume, &link->static_address_messages,
+ static_address_handler, NULL);
}
int link_request_static_addresses(Link *link) {
Address *a;
- Prefix *p;
int r;
assert(link);
@@ -1168,52 +1156,13 @@ int link_request_static_addresses(Link *link) {
return r;
}
- HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
- _cleanup_(address_freep) Address *address = NULL;
-
- if (!p->assign)
- continue;
-
- r = address_new(&address);
- if (r < 0)
- return log_oom();
-
- r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
-
- r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
-
- address->family = AF_INET6;
- address->route_metric = p->route_metric;
-
- r = link_request_static_address(link, TAKE_PTR(address), true);
- if (r < 0)
- return r;
- }
-
- if (in4_addr_is_set(&link->network->dhcp_server_address)) {
- _cleanup_(address_freep) Address *address = NULL;
-
- r = address_new(&address);
- if (r < 0)
- return log_oom();
-
- address->family = AF_INET;
- address->in_addr.in = link->network->dhcp_server_address;
- address->prefixlen = link->network->dhcp_server_address_prefixlen;
- address_set_broadcast(address);
+ r = link_request_radv_addresses(link);
+ if (r < 0)
+ return r;
- /* The same address may be explicitly configured in [Address] or [Network] section.
- * Configure the DHCP server address only when it is not. */
- if (!link_is_static_address_configured(link, address)) {
- r = link_request_static_address(link, TAKE_PTR(address), true);
- if (r < 0)
- return r;
- }
- }
+ r = link_request_dhcp_server_address(link);
+ if (r < 0)
+ return r;
if (link->static_address_messages == 0) {
link->static_addresses_configured = true;
@@ -1226,41 +1175,25 @@ int link_request_static_addresses(Link *link) {
return 0;
}
-static int address_is_ready_to_configure(Link *link, const Address *address) {
- int r;
-
+static bool address_is_ready_to_configure(Link *link, const Address *address) {
assert(link);
assert(address);
if (!link_is_ready_to_configure(link, false))
return false;
- if (link->address_remove_messages > 0)
+ if (FLAGS_SET(address->state, NETWORK_CONFIG_STATE_PROBING))
return false;
- if (address_get(link, address, NULL) >= 0)
- return true;
-
- /* If this is a new address, then refuse adding more than the limit */
+ /* Refuse adding more than the limit */
if (set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
- return log_link_warning_errno(link, SYNTHETIC_ERRNO(E2BIG),
- "Too many addresses are configured, refusing: %m");
-
- if (address->family == AF_INET &&
- address->duplicate_address_detection & ADDRESS_FAMILY_IPV4 &&
- link->hw_addr.length == ETH_ALEN &&
- !ether_addr_is_null(&link->hw_addr.ether))
- return ipv4acd_address_is_ready_to_configure(link, address);
-
- r = address_add(link, address, NULL);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not add address: %m");;
+ return false;
return true;
}
int request_process_address(Request *req) {
- Address *a;
+ Address *existing;
Link *link;
int r;
@@ -1271,26 +1204,18 @@ int request_process_address(Request *req) {
link = req->link;
- r = address_is_ready_to_configure(link, req->address);
- if (r <= 0)
- return r;
-
- r = address_configure(req->address, link, req->netlink_handler);
+ r = address_get(link, req->address, &existing);
if (r < 0)
- return r;
+ return log_link_warning_errno(link, r, "Failed to get address: %m");
- /* To prevent a double decrement on failure in after_configure(). */
- req->message_counter = NULL;
+ if (!address_is_ready_to_configure(link, existing))
+ return 0;
- r = address_get(link, req->address, &a);
+ r = address_configure(req->address, link, req->netlink_handler);
if (r < 0)
- return r;
+ return log_link_warning_errno(link, r, "Failed to configure address: %m");
- if (req->after_configure) {
- r = req->after_configure(req, a);
- if (r < 0)
- return r;
- }
+ address_enter_configuring(existing);
return 1;
}
@@ -1441,10 +1366,14 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
switch (type) {
case RTM_NEWADDR:
- log_address_debug(tmp, address ? "Remembering updated" : "Remembering foreign", link);
- if (!address) {
- /* An address appeared that we did not request */
- r = address_add_foreign(link, tmp, &address);
+ if (address) {
+ address_enter_configured(address);
+ log_address_debug(address, "Remembering updated", link);
+ } else {
+ address_enter_configured(tmp);
+ log_address_debug(tmp, "Received new", link);
+
+ r = address_add(link, tmp);
if (r < 0) {
_cleanup_free_ char *buf = NULL;
@@ -1453,6 +1382,8 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
strnull(buf));
return 0;
}
+
+ address = TAKE_PTR(tmp);
}
/* address_update() logs internally, so we don't need to here. */
@@ -1463,8 +1394,12 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
break;
case RTM_DELADDR:
- log_address_debug(tmp, address ? "Forgetting" : "Kernel removed unknown", link);
- (void) address_drop(address);
+ if (address) {
+ address_enter_removed(address);
+ log_address_debug(address, address->state == 0 ? "Forgetting" : "Removed", link);
+ (void) address_drop(address);
+ } else
+ log_address_debug(tmp, "Kernel removed unknown", link);
break;
@@ -1922,12 +1857,6 @@ int config_parse_duplicate_address_detection(
return 0;
}
-bool address_is_ready(const Address *a) {
- assert(a);
-
- return !(a->flags & IFA_F_TENTATIVE);
-}
-
static int address_section_verify(Address *address) {
if (section_is_invalid(address->section))
return -EINVAL;