diff -uNr systemd-228/Makefile.am systemd-228-duid/Makefile.am
--- systemd-228/Makefile.am 2016-03-30 19:50:11.805796561 +0000
+++ systemd-228-duid/Makefile.am 2016-03-30 20:02:08.116710472 +0000
@@ -5288,6 +5288,8 @@
libnetworkd_core_la_SOURCES = \
src/libsystemd-network/network-internal.h \
src/network/networkd.h \
+ src/network/networkd-conf.h \
+ src/network/networkd-conf.c \
src/network/networkd-link.h \
src/network/networkd-link.c \
src/network/networkd-netdev.h \
@@ -5334,6 +5336,7 @@
src/network/networkd-util.c
nodist_libnetworkd_core_la_SOURCES = \
+ src/network/networkd-gperf.c \
src/network/networkd-network-gperf.c \
src/network/networkd-netdev-gperf.c
@@ -5425,6 +5428,7 @@
org.freedesktop.network1.busname
gperf_gperf_sources += \
+ src/network/networkd-gperf.gperf \
src/network/networkd-network-gperf.gperf \
src/network/networkd-netdev-gperf.gperf
endif
diff -uNr systemd-228/src/libsystemd-network/dhcp-identifier.c systemd-228-duid/src/libsystemd-network/dhcp-identifier.c
--- systemd-228/src/libsystemd-network/dhcp-identifier.c 2016-03-30 19:50:12.282784370 +0000
+++ systemd-228-duid/src/libsystemd-network/dhcp-identifier.c 2016-03-30 19:59:27.311768320 +0000
@@ -45,7 +45,7 @@
if (r < 0)
return r;
- unaligned_write_be16(&duid->type, DHCP6_DUID_EN);
+ unaligned_write_be16(&duid->type, DUID_TYPE_EN);
unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
*len = sizeof(duid->type) + sizeof(duid->en);
diff -uNr systemd-228/src/libsystemd-network/dhcp-identifier.h systemd-228-duid/src/libsystemd-network/dhcp-identifier.h
--- systemd-228/src/libsystemd-network/dhcp-identifier.h 2016-03-30 19:50:12.282784370 +0000
+++ systemd-228-duid/src/libsystemd-network/dhcp-identifier.h 2016-03-30 19:59:27.312768295 +0000
@@ -27,13 +27,23 @@
#include "sparse-endian.h"
#include "unaligned.h"
+typedef enum DUIDType {
+ DUID_TYPE_RAW = 0,
+ DUID_TYPE_LLT = 1,
+ DUID_TYPE_EN = 2,
+ DUID_TYPE_LL = 3,
+ DUID_TYPE_UUID = 4,
+ _DUID_TYPE_MAX,
+ _DUID_TYPE_INVALID = -1,
+} DUIDType;
+
/* RFC 3315 section 9.1:
* A DUID can be no more than 128 octets long (not including the type code).
*/
#define MAX_DUID_LEN 128
struct duid {
- uint16_t type;
+ be16_t type;
union {
struct {
/* DHCP6_DUID_LLT */
@@ -63,3 +73,32 @@
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
+
+static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+ struct duid d;
+
+ assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
+
+ switch (duid_type) {
+ case DUID_TYPE_LLT:
+ if (duid_len <= sizeof(d.llt))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_EN:
+ if (duid_len != sizeof(d.en))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_LL:
+ if (duid_len <= sizeof(d.ll))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_UUID:
+ if (duid_len != sizeof(d.uuid))
+ return -EINVAL;
+ break;
+ default:
+ /* accept unknown type in order to be forward compatible */
+ break;
+ }
+ return 0;
+}
diff -uNr systemd-228/src/libsystemd-network/dhcp6-protocol.h systemd-228-duid/src/libsystemd-network/dhcp6-protocol.h
--- systemd-228/src/libsystemd-network/dhcp6-protocol.h 2016-03-30 19:50:12.289784191 +0000
+++ systemd-228-duid/src/libsystemd-network/dhcp6-protocol.h 2016-03-30 19:59:27.311768320 +0000
@@ -64,13 +64,6 @@
#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC
#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC
-enum {
- DHCP6_DUID_LLT = 1,
- DHCP6_DUID_EN = 2,
- DHCP6_DUID_LL = 3,
- DHCP6_DUID_UUID = 4,
-};
-
enum DHCP6State {
DHCP6_STATE_STOPPED = 0,
DHCP6_STATE_INFORMATION_REQUEST = 1,
diff -uNr systemd-228/src/libsystemd-network/network-internal.c systemd-228-duid/src/libsystemd-network/network-internal.c
--- systemd-228/src/libsystemd-network/network-internal.c 2016-03-30 19:50:12.294784063 +0000
+++ systemd-228-duid/src/libsystemd-network/network-internal.c 2016-03-30 19:59:27.312768295 +0000
@@ -337,6 +337,35 @@
return 0;
}
+int config_parse_iaid(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ uint32_t iaid;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &iaid);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue);
+ return r;
+ }
+
+ *((uint32_t *)data) = iaid;
+
+ return 0;
+}
+
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
diff -uNr systemd-228/src/libsystemd-network/network-internal.h systemd-228-duid/src/libsystemd-network/network-internal.h
--- systemd-228/src/libsystemd-network/network-internal.h 2016-03-30 19:50:12.295784038 +0000
+++ systemd-228-duid/src/libsystemd-network/network-internal.h 2016-03-30 19:59:27.312768295 +0000
@@ -62,6 +62,10 @@
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_iaid(const char *unit, const char *filename, unsigned line,
+ const char *section, unsigned section_line, const char *lvalue,
+ int ltype, const char *rvalue, void *data, void *userdata);
+
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
diff -uNr systemd-228/src/libsystemd-network/sd-dhcp-client.c systemd-228-duid/src/libsystemd-network/sd-dhcp-client.c
--- systemd-228/src/libsystemd-network/sd-dhcp-client.c 2016-03-30 19:50:12.285784293 +0000
+++ systemd-228-duid/src/libsystemd-network/sd-dhcp-client.c 2016-03-30 19:59:27.313768270 +0000
@@ -77,7 +77,7 @@
} _packed_ ll;
struct {
/* 255: Node-specific (RFC 4361) */
- uint32_t iaid;
+ be32_t iaid;
struct duid duid;
} _packed_ ns;
struct {
@@ -291,6 +291,52 @@
return 0;
}
+
+int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
+ uint16_t duid_type, uint8_t *duid, size_t duid_len) {
+ DHCP_CLIENT_DONT_DESTROY(client);
+ int r;
+ assert_return(client, -EINVAL);
+ zero(client->client_id);
+
+ client->client_id.type = 255;
+
+ /* If IAID is not configured, generate it. */
+ if (iaid == 0) {
+ r = dhcp_identifier_set_iaid(client->index, client->mac_addr,
+ client->mac_addr_len,
+ &client->client_id.ns.iaid);
+ if (r < 0)
+ return r;
+ } else
+ client->client_id.ns.iaid = htobe32(iaid);
+
+ /* If DUID is not configured, generate DUID-EN. */
+ if (duid_len == 0) {
+ r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid,
+ &duid_len);
+ if (r < 0)
+ return r;
+ } else {
+ r = dhcp_validate_duid_len(client->client_id.type, duid_len);
+ if (r < 0)
+ return r;
+ client->client_id.ns.duid.type = htobe16(duid_type);
+ memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
+ duid_len += sizeof(client->client_id.ns.duid.type);
+ }
+
+ client->client_id_len = sizeof(client->client_id.type) + duid_len +
+ sizeof(client->client_id.ns.iaid);
+
+ if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
+ log_dhcp_client(client, "Configured IAID+DUID, restarting.");
+ client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
+ sd_dhcp_client_start(client);
+ }
+
+ return 0;
+}
int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
const char *hostname) {
diff -uNr systemd-228/src/libsystemd-network/sd-dhcp6-client.c systemd-228-duid/src/libsystemd-network/sd-dhcp6-client.c
--- systemd-228/src/libsystemd-network/sd-dhcp6-client.c 2016-03-30 19:50:12.296784012 +0000
+++ systemd-228-duid/src/libsystemd-network/sd-dhcp6-client.c 2016-03-30 19:59:27.313768270 +0000
@@ -184,41 +184,29 @@
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
-int sd_dhcp6_client_set_duid(
- sd_dhcp6_client *client,
- uint16_t type,
- uint8_t *duid, size_t duid_len) {
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
+ uint8_t *duid, size_t duid_len) {
+ int r;
assert_return(client, -EINVAL);
- assert_return(duid, -EINVAL);
- assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
-
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
- switch (type) {
- case DHCP6_DUID_LLT:
- if (duid_len <= sizeof(client->duid.llt))
- return -EINVAL;
- break;
- case DHCP6_DUID_EN:
- if (duid_len != sizeof(client->duid.en))
- return -EINVAL;
- break;
- case DHCP6_DUID_LL:
- if (duid_len <= sizeof(client->duid.ll))
- return -EINVAL;
- break;
- case DHCP6_DUID_UUID:
- if (duid_len != sizeof(client->duid.uuid))
- return -EINVAL;
- break;
- default:
- /* accept unknown type in order to be forward compatible */
- break;
+ if (duid_len > 0) {
+ r = dhcp_validate_duid_len(duid_type, duid_len);
+ if (r < 0)
+ return r;
+ client->duid.type = htobe16(duid_type);
+ memcpy(&client->duid.raw.data, duid, duid_len);
+ client->duid_len = duid_len + sizeof(client->duid.type);
}
- client->duid.type = htobe16(type);
- memcpy(&client->duid.raw.data, duid, duid_len);
- client->duid_len = duid_len + sizeof(client->duid.type);
+ return 0;
+}
+
+int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
+ assert_return(client, -EINVAL);
+ assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
+ client->ia_na.id = htobe32(iaid);
return 0;
}
diff -uNr systemd-228/src/network/networkd-conf.c systemd-228-duid/src/network/networkd-conf.c
--- systemd-228/src/network/networkd-conf.c 1970-01-01 00:00:00.000000000 +0000
+++ systemd-228-duid/src/network/networkd-conf.c 2016-03-30 19:59:27.314768245 +0000
@@ -0,0 +1,155 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include <ctype.h>
+
+#include "conf-parser.h"
+#include "def.h"
+#include "dhcp-identifier.h"
+#include "networkd-conf.h"
+#include "string-table.h"
+
+int manager_parse_config_file(Manager *m) {
+ assert(m);
+
+ return config_parse_many(PKGSYSCONFDIR "/networkd.conf",
+ CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
+ "DUID\0",
+ config_item_perf_lookup, networkd_gperf_lookup,
+ false, m);
+}
+
+static const char* const duid_type_table[_DUID_TYPE_MAX] = {
+ [DUID_TYPE_RAW] = "raw",
+ [DUID_TYPE_LLT] = "link-layer-time",
+ [DUID_TYPE_EN] = "vendor",
+ [DUID_TYPE_LL] = "link-layer",
+ [DUID_TYPE_UUID] = "uuid"
+};
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_duid_type, duid_type, DUIDType, "Failed to parse DUID type");
+
+int config_parse_duid_rawdata(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ int r;
+ long byte;
+ char *cbyte, *pnext;
+ const char *pduid = rvalue;
+ size_t count = 0, duid_index = 0;
+ Manager *m;
+ Network *n;
+ DUIDType *duid_type;
+ uint16_t *dhcp_duid_type;
+ size_t *dhcp_duid_len;
+ uint8_t *dhcp_duid;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(userdata);
+
+ if (ltype == DUID_CONFIG_SOURCE_GLOBAL) {
+ m = userdata;
+ duid_type = &m->duid_type;
+ dhcp_duid_type = &m->dhcp_duid_type;
+ dhcp_duid_len = &m->dhcp_duid_len;
+ dhcp_duid = m->dhcp_duid;
+ } else {
+ /* DUID_CONFIG_SOURCE_NETWORK */
+ n = userdata;
+ duid_type = &n->duid_type;
+ dhcp_duid_type = &n->dhcp_duid_type;
+ dhcp_duid_len = &n->dhcp_duid_len;
+ dhcp_duid = n->dhcp_duid;
+ }
+
+ if (*duid_type == _DUID_TYPE_INVALID)
+ *duid_type = DUID_TYPE_RAW;
+
+ switch (*duid_type) {
+ case DUID_TYPE_LLT:
+ /* RawData contains DUID-LLT link-layer address (offset 6) */
+ duid_index = 6;
+ break;
+ case DUID_TYPE_EN:
+ /* RawData contains DUID-EN identifier (offset 4) */
+ duid_index = 4;
+ break;
+ case DUID_TYPE_LL:
+ /* RawData contains DUID-LL link-layer address (offset 2) */
+ duid_index = 2;
+ break;
+ case DUID_TYPE_UUID:
+ /* RawData specifies UUID (offset 0) - fall thru */
+ case DUID_TYPE_RAW:
+ /* First two bytes of RawData is DUID Type - fall thru */
+ default:
+ break;
+ }
+
+ if (*duid_type != DUID_TYPE_RAW)
+ *dhcp_duid_type = (uint16_t)(*duid_type);
+
+ /* RawData contains DUID in format " NN:NN:NN... " */
+ while (true) {
+ r = extract_first_word(&pduid, &cbyte, ":", 0);
+ if (r < 0) {
+ log_error("Failed to read DUID.");
+ return -EINVAL;
+ }
+ if (r == 0)
+ break;
+ if (duid_index >= MAX_DUID_LEN) {
+ log_error("DUID length exceeds maximum length.");
+ return -EINVAL;
+ }
+
+ errno = 0;
+ byte = strtol(cbyte, &pnext, 16);
+ if ((errno == ERANGE && (byte == LONG_MAX || byte == LONG_MIN))
+ || (errno != 0 && byte == 0) || (cbyte == pnext)) {
+ log_error("Invalid DUID byte: %s.", cbyte);
+ return -EINVAL;
+ }
+
+ /* If DUID_TYPE_RAW, first two bytes hold DHCP DUID type code */
+ if ((*duid_type == DUID_TYPE_RAW) && (count < 2)) {
+ *dhcp_duid_type |= (byte << (8 * (1 - count)));
+ count++;
+ continue;
+ }
+
+ dhcp_duid[duid_index++] = byte;
+ }
+
+ *dhcp_duid_len = duid_index;
+
+ return 0;
+}
diff -uNr systemd-228/src/network/networkd-conf.h systemd-228-duid/src/network/networkd-conf.h
--- systemd-228/src/network/networkd-conf.h 1970-01-01 00:00:00.000000000 +0000
+++ systemd-228-duid/src/network/networkd-conf.h 2016-03-30 19:59:27.314768245 +0000
@@ -0,0 +1,36 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "networkd.h"
+
+typedef enum DuidConfigSource {
+ DUID_CONFIG_SOURCE_GLOBAL = 0,
+ DUID_CONFIG_SOURCE_NETWORK,
+} DuidConfigSource;
+
+int manager_parse_config_file(Manager *m);
+
+const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, unsigned length);
+
+int config_parse_duid_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_duid_rawdata(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff -uNr systemd-228/src/network/networkd-dhcp4.c systemd-228-duid/src/network/networkd-dhcp4.c
--- systemd-228/src/network/networkd-dhcp4.c 2016-03-30 19:50:12.411781072 +0000
+++ systemd-228-duid/src/network/networkd-dhcp4.c 2016-03-30 19:59:27.314768245 +0000
@@ -624,7 +624,21 @@
switch (link->network->dhcp_client_identifier) {
case DHCP_CLIENT_ID_DUID:
- /* Library defaults to this. */
+ /* If configured, apply user specified DUID and/or IAID */
+ if (link->network->duid_type != _DUID_TYPE_INVALID)
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ link->network->dhcp_duid_type,
+ link->network->dhcp_duid,
+ link->network->dhcp_duid_len);
+ else
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ link->manager->dhcp_duid_type,
+ link->manager->dhcp_duid,
+ link->manager->dhcp_duid_len);
+ if (r < 0)
+ return r;
break;
case DHCP_CLIENT_ID_MAC:
r = sd_dhcp_client_set_client_id(link->dhcp_client,
diff -uNr systemd-228/src/network/networkd-dhcp6.c systemd-228-duid/src/network/networkd-dhcp6.c
--- systemd-228/src/network/networkd-dhcp6.c 2016-03-30 19:50:12.412781047 +0000
+++ systemd-228-duid/src/network/networkd-dhcp6.c 2016-03-30 19:59:27.314768245 +0000
@@ -232,6 +232,23 @@
if (r < 0)
goto error;
+ r = sd_dhcp6_client_set_iaid(client, link->network->iaid);
+ if (r < 0)
+ goto error;
+
+ if (link->network->duid_type != _DUID_TYPE_INVALID)
+ r = sd_dhcp6_client_set_duid(client,
+ link->network->dhcp_duid_type,
+ link->network->dhcp_duid,
+ link->network->dhcp_duid_len);
+ else
+ r = sd_dhcp6_client_set_duid(client,
+ link->manager->dhcp_duid_type,
+ link->manager->dhcp_duid,
+ link->manager->dhcp_duid_len);
+ if (r < 0)
+ goto error;
+
r = sd_dhcp6_client_set_index(client, link->ifindex);
if (r < 0)
goto error;
diff -uNr systemd-228/src/network/networkd-gperf.gperf systemd-228-duid/src/network/networkd-gperf.gperf
--- systemd-228/src/network/networkd-gperf.gperf 1970-01-01 00:00:00.000000000 +0000
+++ systemd-228-duid/src/network/networkd-gperf.gperf 2016-03-30 19:59:27.314768245 +0000
@@ -0,0 +1,18 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "networkd-conf.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name networkd_gperf_hash
+%define lookup-function-name networkd_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+DUID.Type, config_parse_duid_type, 0, offsetof(Manager, duid_type)
+DUID.RawData, config_parse_duid_rawdata, DUID_CONFIG_SOURCE_GLOBAL, offsetof(Manager, dhcp_duid)
diff -uNr systemd-228/src/network/networkd-link.c systemd-228-duid/src/network/networkd-link.c
--- systemd-228/src/network/networkd-link.c 2016-03-30 19:50:12.435780459 +0000
+++ systemd-228-duid/src/network/networkd-link.c 2016-03-30 19:59:27.315768220 +0000
@@ -2650,6 +2650,21 @@
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
+
+ if (link->network->duid_type != _DUID_TYPE_INVALID)
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ link->network->dhcp_duid_type,
+ link->network->dhcp_duid,
+ link->network->dhcp_duid_len);
+ else
+ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+ link->network->iaid,
+ link->manager->dhcp_duid_type,
+ link->manager->dhcp_duid,
+ link->manager->dhcp_duid_len);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
}
if (link->dhcp6_client) {
@@ -2659,6 +2674,24 @@
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
+
+ r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
+ link->network->iaid);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
+
+ if (link->network->duid_type != _DUID_TYPE_INVALID)
+ r = sd_dhcp6_client_set_duid(link->dhcp6_client,
+ link->network->dhcp_duid_type,
+ link->network->dhcp_duid,
+ link->network->dhcp_duid_len);
+ else
+ r = sd_dhcp6_client_set_duid(link->dhcp6_client,
+ link->manager->dhcp_duid_type,
+ link->manager->dhcp_duid,
+ link->manager->dhcp_duid_len);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
}
}
}
diff -uNr systemd-228/src/network/networkd-manager.c systemd-228-duid/src/network/networkd-manager.c
--- systemd-228/src/network/networkd-manager.c 2016-03-30 19:50:12.415780970 +0000
+++ systemd-228-duid/src/network/networkd-manager.c 2016-03-30 19:59:27.315768220 +0000
@@ -1025,6 +1025,8 @@
if (r < 0)
return r;
+ m->duid_type = _DUID_TYPE_INVALID;
+
*ret = m;
m = NULL;
diff -uNr systemd-228/src/network/networkd-network-gperf.gperf systemd-228-duid/src/network/networkd-network-gperf.gperf
--- systemd-228/src/network/networkd-network-gperf.gperf 2016-03-30 19:50:12.424780740 +0000
+++ systemd-228-duid/src/network/networkd-network-gperf.gperf 2016-03-30 19:59:27.316768196 +0000
@@ -2,6 +2,7 @@
#include <stddef.h>
#include "conf-parser.h"
#include "networkd.h"
+#include "networkd-conf.h"
#include "network-internal.h"
%}
struct ConfigPerfItem;
@@ -26,6 +27,9 @@
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu)
+Link.IAID, config_parse_iaid, 0, offsetof(Network, iaid)
+DUID.Type, config_parse_duid_type, 0, offsetof(Network, duid_type)
+DUID.RawData, config_parse_duid_rawdata, DUID_CONFIG_SOURCE_NETWORK, offsetof(Network, dhcp_duid)
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge)
Network.Bond, config_parse_netdev, 0, offsetof(Network, bond)
diff -uNr systemd-228/src/network/networkd-network.c systemd-228-duid/src/network/networkd-network.c
--- systemd-228/src/network/networkd-network.c 2016-03-30 19:50:12.425780715 +0000
+++ systemd-228-duid/src/network/networkd-network.c 2016-03-30 19:59:27.316768196 +0000
@@ -128,10 +128,12 @@
network->ipv6_accept_ra = -1;
network->ipv6_dad_transmits = -1;
network->ipv6_hop_limit = -1;
+ network->duid_type = _DUID_TYPE_INVALID;
r = config_parse(NULL, filename, file,
"Match\0"
"Link\0"
+ "DUID\0"
"Network\0"
"Address\0"
"Route\0"
diff -uNr systemd-228/src/network/networkd-network.h systemd-228-duid/src/network/networkd-network.h
--- systemd-228/src/network/networkd-network.h 2016-03-30 19:50:12.428780638 +0000
+++ systemd-228-duid/src/network/networkd-network.h 2016-03-30 20:01:19.379946446 +0000
@@ -25,6 +25,7 @@
typedef struct Network Network;
+#include "dhcp-identifier.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-address.h"
@@ -129,6 +130,13 @@
struct ether_addr *mac;
unsigned mtu;
+ uint32_t iaid;
+ /* Value of Type in [DUID] section */
+ DUIDType duid_type;
+ /* DUID type code - RFC 3315 */
+ uint16_t dhcp_duid_type;
+ size_t dhcp_duid_len;
+ uint8_t dhcp_duid[MAX_DUID_LEN];
bool lldp;
diff -uNr systemd-228/src/network/networkd.c systemd-228-duid/src/network/networkd.c
--- systemd-228/src/network/networkd.c 2016-03-30 19:50:12.432780536 +0000
+++ systemd-228-duid/src/network/networkd.c 2016-03-30 19:59:27.313768270 +0000
@@ -23,6 +23,7 @@
#include "capability-util.h"
#include "networkd.h"
+#include "networkd-conf.h"
#include "signal-util.h"
#include "user-util.h"
@@ -91,6 +92,10 @@
goto out;
}
+ r = manager_parse_config_file(m);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse configuration file: %m");
+
r = manager_load_config(m);
if (r < 0) {
log_error_errno(r, "Could not load configuration files: %m");
diff -uNr systemd-228/src/network/networkd.h systemd-228-duid/src/network/networkd.h
--- systemd-228/src/network/networkd.h 2016-03-30 19:50:12.432780536 +0000
+++ systemd-228-duid/src/network/networkd.h 2016-03-30 20:00:46.132789522 +0000
@@ -33,6 +33,7 @@
typedef struct Manager Manager;
+#include "dhcp-identifier.h"
#include "networkd-network.h"
#include "networkd-address-pool.h"
#include "networkd-link.h"
@@ -63,6 +64,13 @@
LIST_HEAD(AddressPool, address_pools);
usec_t network_dirs_ts_usec;
+
+ /* Value of Type in [DUID] section */
+ DUIDType duid_type;
+ /* DUID type code - RFC 3315 */
+ uint16_t dhcp_duid_type;
+ size_t dhcp_duid_len;
+ uint8_t dhcp_duid[MAX_DUID_LEN];
};
extern const char* const network_dirs[];
diff -uNr systemd-228/src/systemd/sd-dhcp-client.h systemd-228-duid/src/systemd/sd-dhcp-client.h
--- systemd-228/src/systemd/sd-dhcp-client.h 2016-03-30 19:50:12.520778286 +0000
+++ systemd-228-duid/src/systemd/sd-dhcp-client.h 2016-03-30 19:59:27.316768196 +0000
@@ -59,6 +59,8 @@
size_t addr_len, uint16_t arp_type);
int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
const uint8_t *data, size_t data_len);
+int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
+ uint16_t duid_type, uint8_t *duid, size_t duid_len);
int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
const uint8_t **data, size_t *data_len);
int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
diff -uNr systemd-228/src/systemd/sd-dhcp6-client.h systemd-228-duid/src/systemd/sd-dhcp6-client.h
--- systemd-228/src/systemd/sd-dhcp6-client.h 2016-03-30 19:50:12.521778261 +0000
+++ systemd-228-duid/src/systemd/sd-dhcp6-client.h 2016-03-30 19:59:27.316768196 +0000
@@ -52,8 +52,9 @@
int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
- size_t duid_len);
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
+ uint8_t *duid, size_t duid_len);
+int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid);
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,