[systemd-devel] [PATCH] sd-dhcp6-client: support custom DUIDs
Tom Gundersen
teg at jklm.no
Thu Oct 2 07:43:44 PDT 2014
Looks good, so applied. However, I added a couple more follow-up
commits changing the API slightly and adding some sanity-checking for
the provided values. Can you check if it still looks ok for you?
Thanks!
Tom
On Fri, Sep 26, 2014 at 10:12 PM, Dan Williams <dcbw at redhat.com> wrote:
> The caller may have an existing DUID that it wants to use, and may
> want to use some other DUID generation scheme than systemd's
> default DUID-EN.
> ---
> src/libsystemd-network/sd-dhcp6-client.c | 43 +++++++++++++++++++++++---------
> src/systemd/sd-dhcp6-client.h | 2 ++
> 2 files changed, 33 insertions(+), 12 deletions(-)
>
> diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
> index c190b56..87a3198 100644
> --- a/src/libsystemd-network/sd-dhcp6-client.c
> +++ b/src/libsystemd-network/sd-dhcp6-client.c
> @@ -35,14 +35,16 @@
> #include "dhcp6-protocol.h"
> #include "dhcp6-internal.h"
> #include "dhcp6-lease-internal.h"
>
> #define SYSTEMD_PEN 43793
> #define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
>
> +#define MAX_DUID_LEN 32
> +
> struct sd_dhcp6_client {
> RefCount n_ref;
>
> enum DHCP6State state;
> sd_event *event;
> int event_priority;
> int index;
> @@ -58,20 +60,16 @@ struct sd_dhcp6_client {
> sd_event_source *receive_message;
> usec_t retransmit_time;
> uint8_t retransmit_count;
> sd_event_source *timeout_resend;
> sd_event_source *timeout_resend_expire;
> sd_dhcp6_client_cb_t cb;
> void *userdata;
> -
> - struct duid_en {
> - uint16_t type; /* DHCP6_DUID_EN */
> - uint32_t pen;
> - uint8_t id[8];
> - } _packed_ duid;
> + uint8_t duid[MAX_DUID_LEN];
> + size_t duid_len;
> };
>
> static const uint16_t default_req_opts[] = {
> DHCP6_OPTION_DNS_SERVERS,
> DHCP6_OPTION_DOMAIN_LIST,
> DHCP6_OPTION_NTP_SERVER,
> };
> @@ -143,14 +141,27 @@ int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
> memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
> else
> memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
>
> return 0;
> }
>
> +int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
> + size_t duid_len)
> +{
> + assert_return(client, -EINVAL);
> + assert_return(duid, -EINVAL);
> + assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
> +
> + memcpy(&client->duid, duid, duid_len);
> + client->duid_len = duid_len;
> +
> + return 0;
> +}
> +
> int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
> uint16_t option) {
> size_t t;
>
> assert_return(client, -EINVAL);
> assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
>
> @@ -304,15 +315,15 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
> r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO,
> client->req_opts_len * sizeof(be16_t),
> client->req_opts);
> if (r < 0)
> return r;
>
> r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
> - sizeof(client->duid), &client->duid);
> + client->duid_len, &client->duid);
> if (r < 0)
> return r;
>
> elapsed_usec = time_now - client->transaction_start;
> if (elapsed_usec < 0xffff * USEC_PER_MSEC * 10)
> elapsed_time = htobe16(elapsed_usec / USEC_PER_MSEC / 10);
> else
> @@ -612,15 +623,15 @@ static int client_parse_message(sd_dhcp6_client *client,
> case DHCP6_OPTION_CLIENTID:
> if (clientid) {
> log_dhcp6_client(client, "%s contains multiple clientids",
> dhcp6_message_type_to_string(message->type));
> return -EINVAL;
> }
>
> - if (optlen != sizeof(client->duid) ||
> + if (optlen != client->duid_len ||
> memcmp(&client->duid, optval, optlen) != 0) {
> log_dhcp6_client(client, "%s DUID does not match",
> dhcp6_message_type_to_string(message->type));
>
> return -EINVAL;
> }
> clientid = true;
> @@ -1112,17 +1123,24 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
>
> return NULL;
> }
>
> return client;
> }
>
> +struct duid_en {
> + uint16_t type; /* DHCP6_DUID_EN */
> + uint32_t pen;
> + uint8_t id[8];
> +} _packed_;
> +
> int sd_dhcp6_client_new(sd_dhcp6_client **ret)
> {
> _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
> + struct duid_en *duid;
> sd_id128_t machine_id;
> int r;
> size_t t;
>
> assert_return(ret, -EINVAL);
>
> client = new0(sd_dhcp6_client, 1);
> @@ -1134,25 +1152,26 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
> client->ia_na.type = DHCP6_OPTION_IA_NA;
>
> client->index = -1;
>
> client->fd = -1;
>
> /* initialize DUID */
> - client->duid.type = htobe16(DHCP6_DUID_EN);
> - client->duid.pen = htobe32(SYSTEMD_PEN);
> + duid = (struct duid_en *) &client->duid;
> + duid->type = htobe16(DHCP6_DUID_EN);
> + duid->pen = htobe32(SYSTEMD_PEN);
>
> r = sd_id128_get_machine(&machine_id);
> if (r < 0)
> return r;
>
> /* a bit of snake-oil perhaps, but no need to expose the machine-id
> directly */
> - siphash24(client->duid.id, &machine_id, sizeof(machine_id),
> - HASH_KEY.bytes);
> + siphash24(duid->id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
> + client->duid_len = sizeof (struct duid_en);
>
> client->req_opts_len = ELEMENTSOF(default_req_opts);
>
> client->req_opts = new0(be16_t, client->req_opts_len);
> if (!client->req_opts)
> return -ENOMEM;
>
> diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
> index 93edcc4..7b7f098 100644
> --- a/src/systemd/sd-dhcp6-client.h
> +++ b/src/systemd/sd-dhcp6-client.h
> @@ -41,14 +41,16 @@ typedef void (*sd_dhcp6_client_cb_t)(sd_dhcp6_client *client, int event,
> void *userdata);
> int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
> sd_dhcp6_client_cb_t cb, void *userdata);
>
> int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
> int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
> const struct ether_addr *mac_addr);
> +int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
> + size_t duid_len);
> int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
> uint16_t option);
>
> int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret);
>
> int sd_dhcp6_client_stop(sd_dhcp6_client *client);
> int sd_dhcp6_client_start(sd_dhcp6_client *client);
> --
> 1.9.3
>
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list