diff options
author | Vinay Kulkarni <vskibum@gmail.com> | 2016-03-31 01:33:55 +0200 |
---|---|---|
committer | Vinay Kulkarni <vskibum@gmail.com> | 2016-03-31 01:33:55 +0200 |
commit | 413708d106afb5ec36464c3fad56f081373320e0 (patch) | |
tree | 706d63a6190036d3015d3100d0935e1a016fbab6 /src | |
parent | Merge pull request #2885 from gbrikis/master (diff) | |
download | systemd-413708d106afb5ec36464c3fad56f081373320e0.tar.xz systemd-413708d106afb5ec36464c3fad56f081373320e0.zip |
DHCP DUID, IAID configuration options
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd-network/dhcp-identifier.c | 2 | ||||
-rw-r--r-- | src/libsystemd-network/dhcp-identifier.h | 41 | ||||
-rw-r--r-- | src/libsystemd-network/dhcp6-protocol.h | 7 | ||||
-rw-r--r-- | src/libsystemd-network/network-internal.c | 29 | ||||
-rw-r--r-- | src/libsystemd-network/network-internal.h | 4 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 48 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp6-client.c | 48 | ||||
-rw-r--r-- | src/network/networkd-conf.c | 155 | ||||
-rw-r--r-- | src/network/networkd-conf.h | 36 | ||||
-rw-r--r-- | src/network/networkd-dhcp4.c | 16 | ||||
-rw-r--r-- | src/network/networkd-dhcp6.c | 17 | ||||
-rw-r--r-- | src/network/networkd-gperf.gperf | 18 | ||||
-rw-r--r-- | src/network/networkd-link.c | 33 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 2 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 4 | ||||
-rw-r--r-- | src/network/networkd-network.c | 2 | ||||
-rw-r--r-- | src/network/networkd-network.h | 8 | ||||
-rw-r--r-- | src/network/networkd.c | 5 | ||||
-rw-r--r-- | src/network/networkd.h | 8 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-client.h | 2 | ||||
-rw-r--r-- | src/systemd/sd-dhcp6-client.h | 5 |
21 files changed, 447 insertions, 43 deletions
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index 1d9ec7be82..4f7d4d8bf2 100644 --- a/src/libsystemd-network/dhcp-identifier.c +++ b/src/libsystemd-network/dhcp-identifier.c @@ -43,7 +43,7 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { 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 --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h index 93f06f5938..babae15c5b 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -25,13 +25,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 */ @@ -61,3 +71,32 @@ struct duid { 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 --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h index ee4bdfb07f..2487c470ab 100644 --- a/src/libsystemd-network/dhcp6-protocol.h +++ b/src/libsystemd-network/dhcp6-protocol.h @@ -62,13 +62,6 @@ enum { #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 --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index cb7252bbeb..0e2d757b2b 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -335,6 +335,35 @@ int config_parse_hwaddr(const char *unit, 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 --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index c8a531ab0f..72432774d7 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -62,6 +62,10 @@ int config_parse_ifalias(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_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 --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 1188b31500..287b6e26fa 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -82,7 +82,7 @@ struct sd_dhcp_client { } _packed_ ll; struct { /* 255: Node-specific (RFC 4361) */ - uint32_t iaid; + be32_t iaid; struct duid duid; } _packed_ ns; struct { @@ -298,6 +298,52 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, 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) { char *new_hostname = NULL; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index af4709d788..ee4fb4fc1e 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -180,41 +180,29 @@ static int client_ensure_duid(sd_dhcp6_client *client) { 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 --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c new file mode 100644 index 0000000000..8b149124b3 --- /dev/null +++ b/src/network/networkd-conf.c @@ -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 --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h new file mode 100644 index 0000000000..efc370f839 --- /dev/null +++ b/src/network/networkd-conf.h @@ -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 --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 68998eabf2..0589ebf227 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -625,7 +625,21 @@ int dhcp4_configure(Link *link) { 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 --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 5f7a005c36..d4b2fbfc57 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -230,6 +230,23 @@ int dhcp6_configure(Link *link) { 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 --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf new file mode 100644 index 0000000000..0625fb335b --- /dev/null +++ b/src/network/networkd-gperf.gperf @@ -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 --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ff4bd76554..eac8123311 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2781,6 +2781,21 @@ int link_update(Link *link, sd_netlink_message *m) { 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) { @@ -2790,6 +2805,24 @@ int link_update(Link *link, sd_netlink_message *m) { 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 --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index b8cb7f875d..d355aaa19c 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1037,6 +1037,8 @@ int manager_new(Manager **ret) { if (r < 0) return r; + m->duid_type = _DUID_TYPE_INVALID; + *ret = m; m = NULL; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index a5d1714293..9793938080 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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.KernelCommandLine, config_parse_net_condition, 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 --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 491b9a3efa..5946ba18dc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -131,10 +131,12 @@ static int network_load_one(Manager *manager, const char *filename) { 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 --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 4a13e2b574..5400a8bc9d 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -24,6 +24,7 @@ typedef struct Network Network; +#include "dhcp-identifier.h" #include "networkd-address.h" #include "networkd-fdb.h" #include "networkd-netdev.h" @@ -144,6 +145,13 @@ struct Network { 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]; LLDPMode lldp_mode; /* LLDP reception */ bool lldp_emit; /* LLDP transmission */ diff --git a/src/network/networkd.c b/src/network/networkd.c index 3a2615e6fd..c8f81a2ca6 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -21,6 +21,7 @@ #include "capability-util.h" #include "networkd.h" +#include "networkd-conf.h" #include "signal-util.h" #include "user-util.h" @@ -89,6 +90,10 @@ int main(int argc, char *argv[]) { 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 --git a/src/network/networkd.h b/src/network/networkd.h index 6bdd8302a0..72a2438ac8 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -31,6 +31,7 @@ typedef struct Manager Manager; +#include "dhcp-identifier.h" #include "networkd-address-pool.h" #include "networkd-link.h" #include "networkd-network.h" @@ -61,6 +62,13 @@ struct Manager { 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 --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index ef45370505..374ff8774e 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -98,6 +98,8 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, 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 --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index 1bedc941aa..4604cb6382 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -85,8 +85,9 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index); 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, |