On Wed, Aug 6, 2014 at 6:17 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.
I have no objections a priori to this patch. But what is the use case? Is there some DUID scheme that is preferable to DUID-EN that we could simply use unconditionally, or do you really depend on the possibility of customizing it? > --- > src/libsystemd-network/sd-dhcp6-client.c | 52 > +++++++++++++++++++----------- > src/libsystemd-network/test-dhcp6-client.c | 4 +-- > src/network/networkd-link.c | 2 +- > src/systemd/sd-dhcp6-client.h | 2 +- > 4 files changed, 38 insertions(+), 22 deletions(-) > > diff --git a/src/libsystemd-network/sd-dhcp6-client.c > b/src/libsystemd-network/sd-dhcp6-client.c > index c6c82eb..8123dc8 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; > @@ -57,20 +59,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, > }; > @@ -300,15 +298,15 @@ static int client_send_message(sd_dhcp6_client *client) > { > 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; > > r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message, > len - optlen); > if (r < 0) > return r; > @@ -585,15 +583,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; > @@ -1059,47 +1057,65 @@ sd_dhcp6_client > *sd_dhcp6_client_unref(sd_dhcp6_client *client) { > > return NULL; > } > > return client; > } > > -int sd_dhcp6_client_new(sd_dhcp6_client **ret) > +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, uint8_t *duid, size_t > duid_len) > { > _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL; > sd_id128_t machine_id; > int r; > size_t t; > > assert_return(ret, -EINVAL); > + if (duid) > + assert_return(duid_len > 0 && duid_len < MAX_DUID_LEN, > -EINVAL); > + else > + assert_return(duid_len == 0, -EINVAL); > > client = new0(sd_dhcp6_client, 1); > if (!client) > return -ENOMEM; > > client->n_ref = REFCNT_INIT; > > 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); > + if (duid) { > + memcpy(&client->duid, duid, duid_len); > + client->duid_len = duid_len; > + } else { > + struct duid_en *en = (struct duid_en *) &client->duid; > > - r = sd_id128_get_machine(&machine_id); > - if (r < 0) > - return r; > + en->type = htobe16(DHCP6_DUID_EN); > + en->pen = htobe32(SYSTEMD_PEN); > > - /* 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); > + 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(en->id, &machine_id, sizeof(machine_id), > + HASH_KEY.bytes); > + client->duid_len = sizeof (*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/libsystemd-network/test-dhcp6-client.c > b/src/libsystemd-network/test-dhcp6-client.c > index 96c68e1..3545935 100644 > --- a/src/libsystemd-network/test-dhcp6-client.c > +++ b/src/libsystemd-network/test-dhcp6-client.c > @@ -52,15 +52,15 @@ static uint8_t test_duid[14] = { }; > > static int test_client_basic(sd_event *e) { > sd_dhcp6_client *client; > > if (verbose) > printf("* %s\n", __FUNCTION__); > > - assert_se(sd_dhcp6_client_new(&client) >= 0); > + assert_se(sd_dhcp6_client_new(&client, NULL, 0) >= 0); > assert_se(client); > > assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); > > assert_se(sd_dhcp6_client_set_index(client, 15) == 0); > assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL); > assert_se(sd_dhcp6_client_set_index(client, -1) == 0); > @@ -538,15 +538,15 @@ static void test_client_solicit_cb(sd_dhcp6_client > *client, int event, > static int test_client_solicit(sd_event *e) { > sd_dhcp6_client *client; > usec_t time_now = now(clock_boottime_or_monotonic()); > > if (verbose) > printf("* %s\n", __FUNCTION__); > > - assert_se(sd_dhcp6_client_new(&client) >= 0); > + assert_se(sd_dhcp6_client_new(&client, NULL, 0) >= 0); > assert_se(client); > > assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); > > assert_se(sd_dhcp6_client_set_index(client, test_index) == 0); > assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0); > > diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c > index accb42b..eff14ca 100644 > --- a/src/network/networkd-link.c > +++ b/src/network/networkd-link.c > @@ -1367,15 +1367,15 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int > event, void *userdata) { > > return; > } > > if (link->dhcp6_client) > return; > > - r = sd_dhcp6_client_new(&link->dhcp6_client); > + r = sd_dhcp6_client_new(&link->dhcp6_client, NULL, 0); > if (r < 0) > return; > > r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0); > if (r < 0) { > link->dhcp6_client = > sd_dhcp6_client_unref(link->dhcp6_client); > return; > diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h > index 93edcc4..b3ec82f 100644 > --- a/src/systemd/sd-dhcp6-client.h > +++ b/src/systemd/sd-dhcp6-client.h > @@ -54,10 +54,10 @@ int sd_dhcp6_client_stop(sd_dhcp6_client *client); > int sd_dhcp6_client_start(sd_dhcp6_client *client); > int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, > int priority); > int sd_dhcp6_client_detach_event(sd_dhcp6_client *client); > sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client); > sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client); > sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client); > -int sd_dhcp6_client_new(sd_dhcp6_client **ret); > +int sd_dhcp6_client_new(sd_dhcp6_client **ret, uint8_t *duid, size_t > duid_len); > > #endif > -- > 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