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 <d...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel