diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index c0d4e9ae67..a885697969 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -436,42 +436,46 @@ static int address_add(Link *link, const Address *in, Address **ret) { } static int address_update(Address *address, const Address *src) { - bool ready; + Link *link; int r; assert(address); assert(address->link); assert(src); - ready = address_is_ready(address); + link = address->link; address->flags = src->flags; address->scope = src->scope; address->cinfo = src->cinfo; - if (IN_SET(address->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; + if (address_is_ready(address) && + address->family == AF_INET6 && + in6_addr_is_link_local(&address->in_addr.in6) && + in6_addr_is_null(&link->ipv6ll_address)) { - link_update_operstate(address->link, true); - link_check_ready(address->link); + link->ipv6ll_address = address->in_addr.in6; - if (!ready && address_is_ready(address)) { - if (address->callback) { - r = address->callback(address); - if (r < 0) - return r; - } - - if (address->family == AF_INET6 && - in6_addr_is_link_local(&address->in_addr.in6) > 0 && - in6_addr_is_null(&address->link->ipv6ll_address)) { - - r = link_ipv6ll_gained(address->link, &address->in_addr.in6); - if (r < 0) - return r; - } + r = link_ipv6ll_gained(link); + if (r < 0) + return r; } + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 0; + + r = address_set_masquerade(address, true); + if (r < 0) + return log_link_warning_errno(link, r, "Could not enable IP masquerading: %m"); + + if (address_is_ready(address) && address->callback) { + r = address->callback(address); + if (r < 0) + return r; + } + + link_update_operstate(link, true); + link_check_ready(link); return 0; } @@ -878,7 +882,7 @@ int link_drop_foreign_addresses(Link *link) { SET_FOREACH(address, link->addresses_foreign) { /* 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) == 1) + if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6)) continue; if (link_address_is_dynamic(link, address)) { @@ -911,8 +915,8 @@ int link_drop_addresses(Link *link) { assert(link); SET_FOREACH(address, link->addresses) { - /* we consider IPv6LL addresses to be managed by the kernel */ - if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6) == 1 && link_ipv6ll_enabled(link)) + /* 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); @@ -1288,10 +1292,6 @@ int request_process_address(Request *req) { return r; } - r = address_set_masquerade(a, true); - if (r < 0) - log_link_warning_errno(link, r, "Could not enable IP masquerading, ignoring: %m"); - return 1; } diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 811940c126..6b5f7ba9c4 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -14,12 +14,13 @@ #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU +typedef struct Address Address; typedef struct Manager Manager; typedef struct Network Network; typedef struct Request Request; typedef int (*address_ready_callback_t)(Address *address); -typedef struct Address { +struct Address { Network *network; NetworkConfigSection *section; @@ -48,7 +49,7 @@ typedef struct Address { /* Called when address become ready */ address_ready_callback_t callback; -} Address; +}; const char* format_lifetime(char *buf, size_t l, uint32_t lifetime) _warn_unused_result_; /* Note: the lifetime of the compound literal is the immediately surrounding block, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index a5a23a33b4..1f840db22b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -701,24 +701,21 @@ static int link_acquire_dynamic_conf(Link *link) { return 0; } -int link_ipv6ll_gained(Link *link, const struct in6_addr *address) { +int link_ipv6ll_gained(Link *link) { int r; assert(link); log_link_info(link, "Gained IPv6LL"); - link->ipv6ll_address = *address; + if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) + return 0; + + r = link_acquire_dynamic_ipv6_conf(link); + if (r < 0) + return r; + link_check_ready(link); - - if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) { - r = link_acquire_dynamic_ipv6_conf(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - } - return 0; } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 79400dee2e..19e212766e 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -236,7 +236,7 @@ bool link_has_carrier(Link *link); bool link_ipv6_enabled(Link *link); bool link_ipv6ll_enabled(Link *link); -int link_ipv6ll_gained(Link *link, const struct in6_addr *address); +int link_ipv6ll_gained(Link *link); bool link_ipv4ll_enabled(Link *link);