int address_update(Address *address, unsigned char flags, unsigned char scope, struct ifa_cacheinfo *cinfo) {
bool ready;
+ int r;
assert(address);
assert(cinfo);
if (address->link) {
link_update_operstate(address->link);
- if (!ready && address_is_ready(address))
+ if (!ready && address_is_ready(address)) {
link_check_ready(address->link);
+
+ if (address->family == AF_INET6 &&
+ in_addr_is_link_local(AF_INET6, &address->in_addr) &&
+ !address->link->ipv6ll_address) {
+ r = link_ipv6ll_gained(address->link);
+ if (r < 0)
+ return r;
+ }
+ }
}
return 0;
!link->ipv4ll_route)
return;
+ if (link_ipv6ll_enabled(link))
+ if (!link->ipv6ll_address)
+ return;
+
if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
!link->dhcp4_configured) ||
(link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
}
}
+static int link_acquire_ipv6_conf(Link *link) {
+ int r;
+
+ assert(link);
+
+ if (link_dhcp6_enabled(link)) {
+ assert(link->dhcp6_client);
+
+ log_link_debug(link, "Acquiring DHCPv6 lease");
+
+ r = sd_dhcp6_client_start(link->dhcp6_client);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
+ }
+
+ if (link_ipv6_accept_ra_enabled(link)) {
+ assert(link->ndisc_router_discovery);
+
+ log_link_debug(link, "Discovering IPv6 routers");
+
+ r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
+ }
+
+ return 0;
+}
+
static int link_acquire_conf(Link *link) {
int r;
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
}
- if (link_dhcp6_enabled(link)) {
- assert(link->dhcp6_client);
-
- log_link_debug(link, "Acquiring DHCPv6 lease");
-
- r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
- }
-
- if (link_ipv6_accept_ra_enabled(link)) {
- assert(link->ndisc_router_discovery);
-
- log_link_debug(link, "Discovering IPv6 routers");
-
- r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
- }
-
if (link_lldp_enabled(link)) {
assert(link->lldp);
r = link_acquire_conf(link);
if (r < 0)
return r;
+
+ if (link->ipv6ll_address) {
+ r = link_acquire_ipv6_conf(link);
+ if (r < 0)
+ return r;
+ }
}
return link_enter_join_netdev(link);
return r;
}
+int link_ipv6ll_gained(Link *link) {
+ int r;
+
+ assert(link);
+
+ log_link_info(link, "Gained IPv6LL");
+
+ link->ipv6ll_address = true;
+ link_check_ready(link);
+
+ if (link->network) {
+ r = link_acquire_ipv6_conf(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return r;
+ }
+ }
+
+ return 0;
+}
+
static int link_carrier_gained(Link *link) {
int r;