sd-dhcp6-client.c revision f12abb48fc510b8b349c05e35ba048134debaf25
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering/***
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering This file is part of systemd.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Copyright (C) 2014 Intel Corporation. All rights reserved.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is free software; you can redistribute it and/or modify it
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering under the terms of the GNU Lesser General Public License as published by
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering (at your option) any later version.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is distributed in the hope that it will be useful, but
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Lesser General Public License for more details.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering You should have received a copy of the GNU Lesser General Public License
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering***/
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <errno.h>
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include <string.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include "udev.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "udev-util.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "virt.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "siphash24.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "util.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "refcnt.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "network-internal.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "sd-dhcp6-client.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "dhcp6-protocol.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "dhcp6-internal.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#define SYSTEMD_PEN 43793
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstruct sd_dhcp6_client {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering RefCount n_ref;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering enum DHCP6State state;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_event *event;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int event_priority;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int index;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering struct ether_addr mac_addr;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering DHCP6IA ia_na;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_dhcp6_client_cb_t cb;
3b97fcbd28f92a1e51887fef5de8844a89bde523Lennart Poettering void *userdata;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct duid_en {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering uint16_t type; /* DHCP6_DUID_EN */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering uint32_t pen;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering uint8_t id[8];
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering } _packed_ duid;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering};
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_dhcp6_client_cb_t cb, void *userdata)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->cb = cb;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->userdata = userdata;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(interface_index >= -1, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->index = interface_index;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek const struct ether_addr *mac_addr)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (mac_addr)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic sd_dhcp6_client *client_notify(sd_dhcp6_client *client, int event) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client->cb) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client = sd_dhcp6_client_ref(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->cb(client, event, client->userdata);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt client = sd_dhcp6_client_unref(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return client;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_initialize(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->ia_na.timeout_t1 =
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_event_source_unref(client->ia_na.timeout_t1);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->ia_na.timeout_t2 =
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_event_source_unref(client->ia_na.timeout_t2);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->state = DHCP6_STATE_STOPPED;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic sd_dhcp6_client *client_stop(sd_dhcp6_client *client, int error) {
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering assert_return(client, NULL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client = client_notify(client, error);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client_initialize(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return client;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_ensure_iaid(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *name = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering uint64_t id;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client->ia_na.id)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (detect_container(NULL) <= 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* not in a container, udev will be around */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_udev_unref_ struct udev *udev;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_udev_device_unref_ struct udev_device *device;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char ifindex_str[2 + DECIMAL_STR_MAX(int)];
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering udev = udev_new();
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!udev)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -ENOMEM;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sprintf(ifindex_str, "n%d", client->index);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering device = udev_device_new_from_device_id(udev, ifindex_str);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!device)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -errno;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (udev_device_get_is_initialized(device) <= 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* not yet ready */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -EBUSY;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering name = net_get_name(device);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (name)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek else
b9c488f60050248b35640f28e4d00958702ba1c3Eelco Dolstra /* fall back to mac address if no predictable name available */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering siphash24((uint8_t*)&id, &client->mac_addr, ETH_ALEN,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering HASH_KEY.bytes);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* fold into 32 bits */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->ia_na.id = (id & 0xffffffff) ^ (id >> 32);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_start(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client->event, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client->index > 0, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = client_ensure_iaid(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (r < 0)
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering return r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_stop(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client_stop(client, DHCP6_EVENT_STOP);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_start(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int r = 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
dc61b7e45d89a69f0469ab7b3289cdde7fcc55abTorstein Husebø assert_return(client->event, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client->index > 0, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = client_initialize(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (r < 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return client_start(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int priority)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering int r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(!client->event, -EBUSY);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (event)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->event = sd_event_ref(event);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = sd_event_default(&client->event);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (r < 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->event_priority = priority;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->event = sd_event_unref(client->event);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return client->event;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_se(REFCNT_INC(client->n_ref) >= 2);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return client;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client && REFCNT_DEC(client->n_ref) <= 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client_initialize(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_dhcp6_client_detach_event(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(client);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return NULL;
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek }
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek return client;
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek}
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#define _cleanup_dhcp6_client_free_ _cleanup_(sd_dhcp6_client_unrefp)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_new(sd_dhcp6_client **ret)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering{
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_dhcp6_client_free_ sd_dhcp6_client *client = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_id128_t machine_id;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering assert_return(ret, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client = new0(sd_dhcp6_client, 1);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -ENOMEM;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->n_ref = REFCNT_INIT;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar client->ia_na.type = DHCP6_OPTION_IA_NA;
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar client->index = -1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* initialize DUID */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->duid.type = htobe16(DHCP6_DUID_EN);
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek client->duid.pen = htobe32(SYSTEMD_PEN);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = sd_id128_get_machine(&machine_id);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (r < 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* a bit of snake-oil perhaps, but no need to expose the machine-id
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering directly */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering siphash24(client->duid.id, &machine_id, sizeof(machine_id),
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering HASH_KEY.bytes);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering *ret = client;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering