summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-address.c6
-rw-r--r--src/network/networkd-dhcp6.c3
-rw-r--r--src/network/networkd-link.c20
-rw-r--r--src/network/networkd-link.h4
-rw-r--r--src/network/networkd-ndisc.c6
5 files changed, 24 insertions, 15 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index c0562e5788..1ce1f4d8d6 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -347,9 +347,9 @@ int address_update(Address *address, unsigned char flags, unsigned char scope, s
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);
+ in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
+ in_addr_is_null(AF_INET6, (const union in_addr_union*) &address->link->ipv6ll_address) > 0) {
+ r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
if (r < 0)
return r;
}
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index f83ff54369..e67e51f7ef 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -211,6 +211,9 @@ int dhcp6_configure(Link *link) {
assert(link);
+ if (link->dhcp6_client)
+ return 0;
+
r = sd_dhcp6_client_new(&client);
if (r < 0)
return r;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index a415035887..01d5942ce5 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -615,7 +615,7 @@ void link_check_ready(Link *link) {
return;
if (link_ipv6ll_enabled(link))
- if (!link->ipv6ll_address)
+ if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
return;
if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
@@ -1260,11 +1260,16 @@ static int link_acquire_ipv6_conf(Link *link) {
if (link_dhcp6_enabled(link)) {
assert(link->dhcp6_client);
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
log_link_debug(link, "Acquiring DHCPv6 lease");
+ r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
+ if (r < 0 && r != -EBUSY)
+ return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
+
r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0)
+ if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
}
@@ -1274,7 +1279,7 @@ static int link_acquire_ipv6_conf(Link *link) {
log_link_debug(link, "Discovering IPv6 routers");
r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
- if (r < 0)
+ if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
}
@@ -2089,7 +2094,8 @@ static int link_configure(Link *link) {
return r;
}
- if (link_dhcp6_enabled(link)) {
+ if (link_dhcp6_enabled(link) ||
+ link_ipv6_accept_ra_enabled(link)) {
r = dhcp6_configure(link);
if (r < 0)
return r;
@@ -2121,7 +2127,7 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
- if (link->ipv6ll_address) {
+ if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
r = link_acquire_ipv6_conf(link);
if (r < 0)
return r;
@@ -2472,14 +2478,14 @@ failed:
return r;
}
-int link_ipv6ll_gained(Link *link) {
+int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
int r;
assert(link);
log_link_info(link, "Gained IPv6LL");
- link->ipv6ll_address = true;
+ link->ipv6ll_address = *address;
link_check_ready(link);
if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index b564bcbca0..aa2235b11d 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -69,6 +69,7 @@ struct Link {
char *ifname;
char *state_file;
struct ether_addr mac;
+ struct in6_addr ipv6ll_address;
uint32_t mtu;
struct udev_device *udev_device;
@@ -101,7 +102,6 @@ struct Link {
sd_ipv4ll *ipv4ll;
bool ipv4ll_address:1;
bool ipv4ll_route:1;
- bool ipv6ll_address:1;
bool static_configured;
@@ -144,7 +144,7 @@ int link_save(Link *link);
int link_carrier_reset(Link *link);
bool link_has_carrier(Link *link);
-int link_ipv6ll_gained(Link *link);
+int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
int link_set_mtu(Link *link, uint32_t mtu);
int link_set_hostname(Link *link, const char *hostname);
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 2ff87c32eb..ce9e513ceb 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -75,7 +75,7 @@ static void ndisc_prefix_autonomous_handler(sd_ndisc *nd, const struct in6_addr
address->family = AF_INET6;
address->in_addr.in6 = *prefix;
if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0)
- memcpy(&address->in_addr.in6 + 8, &link->network->ipv6_token + 8, 8);
+ memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8);
else {
/* see RFC4291 section 2.5.1 */
address->in_addr.in6.__in6_u.__u6_addr8[8] = link->mac.ether_addr_octet[0];
@@ -159,7 +159,7 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
dhcp6_request_address(link);
r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0 && r != -EALREADY)
+ if (r < 0 && r != -EBUSY)
log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
}
@@ -205,7 +205,7 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
dhcp6_request_address(link);
r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0 && r != -EALREADY)
+ if (r < 0 && r != -EBUSY)
log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
link->ndisc_configured = true;