Skip to content

Commit

Permalink
Merge pull request #28896 from pelaufer/dhcp_dbus_notify
Browse files Browse the repository at this point in the history
Add DHCP client state and change notification to networkd dbus interface
  • Loading branch information
yuwata committed Sep 4, 2023
2 parents 6d05778 + e1ef777 commit 47d8770
Show file tree
Hide file tree
Showing 20 changed files with 402 additions and 24 deletions.
8 changes: 8 additions & 0 deletions src/libsystemd-network/dhcp-client-internal.h
@@ -1,4 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

#include "sd-dhcp-client.h"

extern const struct hash_ops dhcp_option_hash_ops;

int dhcp_client_set_state_callback(
sd_dhcp_client *client,
sd_dhcp_client_callback_t cb,
void *userdata);
int dhcp_client_get_state(sd_dhcp_client *client);
3 changes: 1 addition & 2 deletions src/libsystemd-network/dhcp-internal.h
Expand Up @@ -11,6 +11,7 @@

#include "sd-dhcp-client.h"

#include "dhcp-client-internal.h"
#include "dhcp-protocol.h"
#include "ether-addr-util.h"
#include "network-common.h"
Expand All @@ -29,8 +30,6 @@ typedef struct DHCPServerData {
size_t size;
} DHCPServerData;

extern const struct hash_ops dhcp_option_hash_ops;

typedef struct sd_dhcp_client sd_dhcp_client;

int dhcp_network_bind_raw_socket(
Expand Down
18 changes: 18 additions & 0 deletions src/libsystemd-network/dhcp-protocol.c
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "dhcp-protocol.h"
#include "string-table.h"

static const char* const dhcp_state_table[_DHCP_STATE_MAX] = {
[DHCP_STATE_STOPPED] = "stopped",
[DHCP_STATE_INIT] = "initialization",
[DHCP_STATE_SELECTING] = "selecting",
[DHCP_STATE_INIT_REBOOT] = "init-reboot",
[DHCP_STATE_REBOOTING] = "rebooting",
[DHCP_STATE_REQUESTING] = "requesting",
[DHCP_STATE_BOUND] = "bound",
[DHCP_STATE_RENEWING] = "renewing",
[DHCP_STATE_REBINDING] = "rebinding",
};

DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dhcp_state, DHCPState);
22 changes: 13 additions & 9 deletions src/libsystemd-network/dhcp-protocol.h
Expand Up @@ -55,15 +55,17 @@ enum {
};

enum DHCPState {
DHCP_STATE_STOPPED = 0,
DHCP_STATE_INIT = 1,
DHCP_STATE_SELECTING = 2,
DHCP_STATE_INIT_REBOOT = 3,
DHCP_STATE_REBOOTING = 4,
DHCP_STATE_REQUESTING = 5,
DHCP_STATE_BOUND = 6,
DHCP_STATE_RENEWING = 7,
DHCP_STATE_REBINDING = 8,
DHCP_STATE_STOPPED,
DHCP_STATE_INIT,
DHCP_STATE_SELECTING,
DHCP_STATE_INIT_REBOOT,
DHCP_STATE_REBOOTING,
DHCP_STATE_REQUESTING,
DHCP_STATE_BOUND,
DHCP_STATE_RENEWING,
DHCP_STATE_REBINDING,
_DHCP_STATE_MAX,
_DHCP_STATE_INVALID = -EINVAL,
};

typedef enum DHCPState DHCPState;
Expand Down Expand Up @@ -107,3 +109,5 @@ enum {
DHCP_FQDN_FLAG_E = (1 << 2),
DHCP_FQDN_FLAG_N = (1 << 3),
};

const char *dhcp_state_to_string(DHCPState s) _const_;
10 changes: 10 additions & 0 deletions src/libsystemd-network/dhcp6-client-internal.h
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

#include "sd-dhcp6-client.h"

int dhcp6_client_set_state_callback(
sd_dhcp6_client *client,
sd_dhcp6_client_callback_t cb,
void *userdata);
int dhcp6_client_get_state(sd_dhcp6_client *client);
3 changes: 3 additions & 0 deletions src/libsystemd-network/dhcp6-internal.h
Expand Up @@ -12,6 +12,7 @@
#include "sd-dhcp6-client.h"

#include "dhcp-identifier.h"
#include "dhcp6-client-internal.h"
#include "dhcp6-option.h"
#include "dhcp6-protocol.h"
#include "ether-addr-util.h"
Expand Down Expand Up @@ -79,6 +80,8 @@ struct sd_dhcp6_client {

sd_dhcp6_client_callback_t callback;
void *userdata;
sd_dhcp6_client_callback_t state_callback;
void *state_userdata;
bool send_release;

/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
Expand Down
1 change: 1 addition & 0 deletions src/libsystemd-network/meson.build
Expand Up @@ -6,6 +6,7 @@ sources = files(
'dhcp-network.c',
'dhcp-option.c',
'dhcp-packet.c',
'dhcp-protocol.c',
'dhcp6-network.c',
'dhcp6-option.c',
'dhcp6-protocol.c',
Expand Down
59 changes: 48 additions & 11 deletions src/libsystemd-network/sd-dhcp-client.c
Expand Up @@ -118,6 +118,8 @@ struct sd_dhcp_client {
sd_event_source *timeout_expire;
sd_dhcp_client_callback_t callback;
void *userdata;
sd_dhcp_client_callback_t state_callback;
void *state_userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
int ip_service_type;
Expand Down Expand Up @@ -226,6 +228,19 @@ int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret) {
return 0;
}

int dhcp_client_set_state_callback(
sd_dhcp_client *client,
sd_dhcp_client_callback_t cb,
void *userdata) {

assert_return(client, -EINVAL);

client->state_callback = cb;
client->state_userdata = userdata;

return 0;
}

int sd_dhcp_client_set_callback(
sd_dhcp_client *client,
sd_dhcp_client_callback_t cb,
Expand Down Expand Up @@ -730,6 +745,27 @@ int sd_dhcp_client_set_fallback_lease_lifetime(sd_dhcp_client *client, uint32_t
return 0;
}

static void client_set_state(sd_dhcp_client *client, DHCPState state) {
assert(client);

if (client->state == state)
return;

log_dhcp_client(client, "State changed: %s -> %s",
dhcp_state_to_string(client->state), dhcp_state_to_string(state));

client->state = state;

if (client->state_callback)
client->state_callback(client, state, client->state_userdata);
}

int dhcp_client_get_state(sd_dhcp_client *client) {
assert_return(client, -EINVAL);

return client->state;
}

static int client_notify(sd_dhcp_client *client, int event) {
assert(client);

Expand All @@ -753,7 +789,7 @@ static int client_initialize(sd_dhcp_client *client) {

client->attempt = 0;

client->state = DHCP_STATE_STOPPED;
client_set_state(client, DHCP_STATE_STOPPED);
client->xid = 0;

client->lease = sd_dhcp_lease_unref(client->lease);
Expand Down Expand Up @@ -1183,6 +1219,7 @@ static int client_send_request(sd_dhcp_client *client) {
case DHCP_STATE_REBOOTING:
case DHCP_STATE_BOUND:
case DHCP_STATE_STOPPED:
default:
return -EINVAL;
}

Expand Down Expand Up @@ -1307,7 +1344,7 @@ static int client_timeout_resend(
case DHCP_STATE_INIT:
r = client_send_discover(client);
if (r >= 0) {
client->state = DHCP_STATE_SELECTING;
client_set_state(client, DHCP_STATE_SELECTING);
client->attempt = 0;
} else if (client->attempt >= client->max_attempts)
goto error;
Expand All @@ -1330,7 +1367,7 @@ static int client_timeout_resend(
goto error;

if (client->state == DHCP_STATE_INIT_REBOOT)
client->state = DHCP_STATE_REBOOTING;
client_set_state(client, DHCP_STATE_REBOOTING);

client->request_sent = time_now;
break;
Expand All @@ -1340,6 +1377,7 @@ static int client_timeout_resend(
break;

case DHCP_STATE_STOPPED:
default:
r = -EINVAL;
goto error;
}
Expand Down Expand Up @@ -1479,7 +1517,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
client->receive_message = sd_event_source_disable_unref(client->receive_message);
client->fd = safe_close(client->fd);

client->state = DHCP_STATE_REBINDING;
client_set_state(client, DHCP_STATE_REBINDING);
client->attempt = 0;

r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
Expand All @@ -1500,9 +1538,9 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
DHCP_CLIENT_DONT_DESTROY(client);

if (client->lease)
client->state = DHCP_STATE_RENEWING;
client_set_state(client, DHCP_STATE_RENEWING);
else if (client->state != DHCP_STATE_INIT)
client->state = DHCP_STATE_INIT_REBOOT;
client_set_state(client, DHCP_STATE_INIT_REBOOT);
client->attempt = 0;

return client_initialize_time_events(client);
Expand Down Expand Up @@ -1782,7 +1820,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
if (r < 0)
goto error;

client->state = DHCP_STATE_REQUESTING;
client_set_state(client, DHCP_STATE_REQUESTING);
client->attempt = 0;

r = event_reset_time(client->event, &client->timeout_resend,
Expand Down Expand Up @@ -1831,7 +1869,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client->receive_message = sd_event_source_disable_unref(client->receive_message);
client->fd = safe_close(client->fd);

client->state = DHCP_STATE_BOUND;
client_set_state(client, DHCP_STATE_BOUND);
client->attempt = 0;

client->last_addr = client->lease->address;
Expand Down Expand Up @@ -2047,7 +2085,7 @@ int sd_dhcp_client_send_renew(sd_dhcp_client *client) {

client->start_delay = 0;
client->attempt = 1;
client->state = DHCP_STATE_RENEWING;
client_set_state(client, DHCP_STATE_RENEWING);

return client_initialize_time_events(client);
}
Expand Down Expand Up @@ -2083,7 +2121,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
the client MAY issue a DHCPREQUEST to try to reclaim the current
address. */
if (client->last_addr && !client->anonymize)
client->state = DHCP_STATE_INIT_REBOOT;
client_set_state(client, DHCP_STATE_INIT_REBOOT);

r = client_start(client);
if (r >= 0)
Expand Down Expand Up @@ -2176,7 +2214,6 @@ int sd_dhcp_client_stop(sd_dhcp_client *client) {
DHCP_CLIENT_DONT_DESTROY(client);

client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
client->state = DHCP_STATE_STOPPED;

return 0;
}
Expand Down
22 changes: 22 additions & 0 deletions src/libsystemd-network/sd-dhcp6-client.c
Expand Up @@ -47,6 +47,19 @@ int sd_dhcp6_client_set_callback(
return 0;
}

int dhcp6_client_set_state_callback(
sd_dhcp6_client *client,
sd_dhcp6_client_callback_t cb,
void *userdata) {

assert_return(client, -EINVAL);

client->state_callback = cb;
client->state_userdata = userdata;

return 0;
}

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);
Expand Down Expand Up @@ -553,6 +566,15 @@ static void client_set_state(sd_dhcp6_client *client, DHCP6State state) {
dhcp6_state_to_string(client->state), dhcp6_state_to_string(state));

client->state = state;

if (client->state_callback)
client->state_callback(client, state, client->state_userdata);
}

int dhcp6_client_get_state(sd_dhcp6_client *client) {
assert_return(client, -EINVAL);

return client->state;
}

static void client_notify(sd_dhcp6_client *client, int event) {
Expand Down
2 changes: 2 additions & 0 deletions src/network/meson.build
Expand Up @@ -43,7 +43,9 @@ sources = files(
'networkd-dhcp-server-bus.c',
'networkd-dhcp-server-static-lease.c',
'networkd-dhcp-server.c',
'networkd-dhcp4-bus.c',
'networkd-dhcp4.c',
'networkd-dhcp6-bus.c',
'networkd-dhcp6.c',
'networkd-ipv4acd.c',
'networkd-ipv4ll.c',
Expand Down
2 changes: 1 addition & 1 deletion src/network/networkd-dhcp-common.c
Expand Up @@ -6,7 +6,7 @@
#include "bus-error.h"
#include "bus-locator.h"
#include "dhcp-identifier.h"
#include "dhcp-internal.h"
#include "dhcp-client-internal.h"
#include "dhcp6-internal.h"
#include "escape.h"
#include "hexdecoct.h"
Expand Down

0 comments on commit 47d8770

Please sign in to comment.