int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(ifindex > 0, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
client->ifindex = ifindex;
return 0;
const struct in6_addr *local_address) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(local_address, -EINVAL);
assert_return(in6_addr_is_link_local(local_address) > 0, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
client->local_address = *local_address;
assert_return(client, -EINVAL);
assert_return(addr, -EINVAL);
assert_return(addr_len <= HW_ADDR_MAX_SIZE, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+
+ /* Unlike the other setters, it is OK to set a new MAC address while the client is running,
+ * as the MAC address is used only when setting DUID or IAID. */
if (arp_type == ARPHRD_ETHER)
assert_return(addr_len == ETH_ALEN, -EINVAL);
_cleanup_free_ DHCP6Address *prefix = NULL;
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
if (!pd_prefix) {
/* clear previous assignments. */
int r;
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(v, -EINVAL);
r = ordered_hashmap_ensure_put(&client->vendor_options, &dhcp6_option_hash_ops, v, v);
}
static int client_ensure_duid(sd_dhcp6_client *client) {
+ assert(client);
+
if (client->duid_len != 0)
return 0;
int r;
assert_return(client, -EINVAL);
- assert_return(duid_len == 0 || duid != NULL, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
+ assert_return(duid_len == 0 || duid, -EINVAL);
if (duid) {
r = dhcp_validate_duid_len(duid_type, duid_len, true);
int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
client->ia_na.header.id = htobe32(iaid);
client->ia_pd.header.id = htobe32(iaid);
const char *fqdn) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
/* Make sure FQDN qualifies as DNS and as Linux hostname */
if (fqdn &&
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled) {
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
client->information_request = enabled;
size_t t;
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
if (!dhcp6_option_can_request(option))
return -EINVAL;
int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, const char *mudurl) {
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(mudurl, -EINVAL);
assert_return(strlen(mudurl) <= UINT8_MAX, -EINVAL);
assert_return(http_url_is_valid(mudurl), -EINVAL);
char **s;
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(!strv_isempty(user_class), -EINVAL);
STRV_FOREACH(p, user_class) {
char **s;
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
assert_return(!strv_isempty(vendor_class), -EINVAL);
STRV_FOREACH(p, vendor_class) {
int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, int delegation) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
SET_FLAG(client->request_ia, DHCP6_REQUEST_IA_PD, delegation);
int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
SET_FLAG(client->request_ia, DHCP6_REQUEST_IA_NA, request);
case DHCP6_STATE_REBIND:
return DHCP6_MESSAGE_REBIND;
default:
- return -EINVAL;
+ assert_not_reached();
}
}
_cleanup_free_ DHCP6Message *message = NULL;
struct in6_addr all_servers =
IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
- DHCP6MessageType message_type;
struct sd_dhcp6_option *j;
size_t len, optlen = 512;
uint8_t *opt;
opt = (uint8_t *)(message + 1);
message->transaction_id = client->transaction_id;
-
- message_type = client_message_type_from_state(client);
- if (message_type < 0)
- return message_type;
-
- message->type = message_type;
+ message->type = client_message_type_from_state(client);
switch (client->state) {
case DHCP6_STATE_INFORMATION_REQUEST:
case DHCP6_STATE_STOPPED:
case DHCP6_STATE_BOUND:
- return -EINVAL;
default:
assert_not_reached();
}
usec_t init_retransmit_time, max_retransmit_time;
int r;
- assert(s);
assert(client->event);
switch (client->state) {
static int client_start_transaction(sd_dhcp6_client *client, DHCP6State state) {
int r;
- assert_return(client, -EINVAL);
- assert_return(client->event, -EINVAL);
- assert_return(client->ifindex > 0, -EINVAL);
+ assert(client);
+ assert(client->event);
switch (state) {
case DHCP6_STATE_INFORMATION_REQUEST:
}
static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_dhcp6_client *client = userdata;
+ sd_dhcp6_client *client = ASSERT_PTR(userdata);
DHCP6_CLIENT_DONT_DESTROY(client);
DHCP6State state;
- assert(s);
- assert(client);
- assert(client->event);
-
(void) event_source_disable(client->timeout_expire);
(void) event_source_disable(client->timeout_t2);
(void) event_source_disable(client->timeout_t1);
}
static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_dhcp6_client *client = userdata;
-
- assert(s);
- assert(client);
- assert(client->lease);
+ sd_dhcp6_client *client = ASSERT_PTR(userdata);
(void) event_source_disable(client->timeout_t2);
(void) event_source_disable(client->timeout_t1);
}
static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_dhcp6_client *client = userdata;
-
- assert(s);
- assert(client);
- assert(client->lease);
+ sd_dhcp6_client *client = ASSERT_PTR(userdata);
(void) event_source_disable(client->timeout_t1);
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
int r;
+ assert(client);
+ assert(message);
+
if (message->type != DHCP6_MESSAGE_REPLY)
return log_invalid_message_type(client, message);
revents,
void *userdata) {
- sd_dhcp6_client *client = userdata;
+ sd_dhcp6_client *client = ASSERT_PTR(userdata);
DHCP6_CLIENT_DONT_DESTROY(client);
/* This needs to be initialized with zero. See #20741. */
CMSG_BUFFER_TYPE(CMSG_SPACE_TIMEVAL) control = {};
struct in6_addr *server_address = NULL;
ssize_t buflen, len;
- assert(s);
- assert(client);
- assert(client->event);
-
buflen = next_datagram_size_fd(fd);
if (buflen < 0) {
if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
assert_return(client->event, -EINVAL);
assert_return(client->ifindex > 0, -EINVAL);
assert_return(in6_addr_is_link_local(&client->local_address) > 0, -EINVAL);
-
- if (client->state != DHCP6_STATE_STOPPED)
- return -EBUSY;
-
- if (!client->information_request && client->request_ia == 0)
- return -EINVAL;
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
+ assert_return(client->information_request || client->request_ia != 0, -EINVAL);
/* Even if the client is in the STOPPED state, the lease acquired in the previous information
* request may be stored. */
assert_return(client, -EINVAL);
assert_return(!client->event, -EBUSY);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
if (event)
client->event = sd_event_ref(event);
int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
client->event = sd_event_unref(client->event);
}
static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
- assert(client);
+ if (!client)
+ return NULL;
sd_dhcp6_lease_unref(client->lease);
sd_event_source_disable_unref(client->timeout_expire);
sd_event_source_disable_unref(client->timeout_t1);
sd_event_source_disable_unref(client->timeout_t2);
+ sd_event_unref(client->event);
client->fd = safe_close(client->fd);
- sd_dhcp6_client_detach_event(client);
-
free(client->req_opts);
free(client->fqdn);
free(client->mudurl);