summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp6-client.c
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-11-16 17:43:08 +0100
committerTom Gundersen <teg@jklm.no>2015-11-17 14:17:41 +0100
commitc601ebf79f0c54be14d3c16f0f484c0335cdeec4 (patch)
treec13fb6b3eb731d5f885bf0bed63935d84bb6fc02 /src/libsystemd-network/sd-dhcp6-client.c
parentfb84d8966e5ce49b0c705768bb4da4956c4e529a (diff)
sd-dhcp6-client: bind to link-local address
This ensures that several DHCPv6 clients can run on separate interfaces simultaneously.
Diffstat (limited to 'src/libsystemd-network/sd-dhcp6-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index a9518791b3..801331d270 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -32,6 +32,7 @@
#include "dhcp6-lease-internal.h"
#include "dhcp6-protocol.h"
#include "fd-util.h"
+#include "in-addr-util.h"
#include "network-internal.h"
#include "random-util.h"
#include "string-table.h"
@@ -46,6 +47,7 @@ struct sd_dhcp6_client {
sd_event *event;
int event_priority;
int index;
+ struct in6_addr local_address;
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
size_t mac_addr_len;
uint16_t arp_type;
@@ -133,6 +135,18 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
return 0;
}
+int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address) {
+ assert_return(client, -EINVAL);
+ assert_return(local_address, -EINVAL);
+ assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL);
+
+ assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
+ client->local_address = *local_address;
+
+ return 0;
+}
+
int sd_dhcp6_client_set_mac(
sd_dhcp6_client *client,
const uint8_t *addr, size_t addr_len,
@@ -1135,6 +1149,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL);
assert_return(client->index > 0, -EINVAL);
+ assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) &client->local_address) > 0, -EINVAL);
if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
return -EBUSY;
@@ -1151,7 +1166,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
if (r < 0)
return r;
- r = dhcp6_network_bind_udp_socket(client->index, NULL);
+ r = dhcp6_network_bind_udp_socket(client->index, &client->local_address);
if (r < 0)
return r;