mirror of
https://github.com/systemd/systemd.git
synced 2025-01-12 13:18:14 +03:00
Merge pull request #19271 from yuwata/dhcp-duid-uuid
network: fix issues arround DHCP DUID-UUID
This commit is contained in:
commit
6f4a5f25fc
@ -98,15 +98,12 @@
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[DHCP] Section Options</title>
|
||||
<title>[DHCPv4] Section Options</title>
|
||||
|
||||
<para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP
|
||||
protocol. DHCPv6 client protocol sends the DHCP Unique Identifier and the interface
|
||||
Identity Association Identifier (IAID) to a DHCP server when acquiring a dynamic IPv6
|
||||
address. DHCPv4 client protocol sends IAID and DUID to the DHCP server when acquiring
|
||||
a dynamic IPv4 address if <option>ClientIdentifier=duid</option>. IAID and DUID allows
|
||||
a DHCP server to uniquely identify the machine and the interface requesting a DHCP IP.
|
||||
To configure IAID and ClientIdentifier, see
|
||||
<para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP protocol. DHCPv4
|
||||
client protocol sends IAID and DUID to the DHCP server when acquiring a dynamic IPv4 address if
|
||||
<option>ClientIdentifier=duid</option>. IAID and DUID allows a DHCP server to uniquely identify the
|
||||
machine and the interface requesting a DHCP IP address. To configure IAID and ClientIdentifier, see
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
@ -188,6 +185,28 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[DHCPv6] Section Options</title>
|
||||
|
||||
<para>This section configures the DHCP Unique Identifier (DUID) value used by DHCPv6 protocol.
|
||||
DHCPv6 client protocol sends the DHCP Unique Identifier and the interface Identity Association
|
||||
Identifier (IAID) to a DHCPv6 server when acquiring a dynamic IPv6 address. IAID and DUID allows a
|
||||
DHCPv6 server to uniquely identify the machine and the interface requesting a DHCP IP address. To
|
||||
configure IAID, see
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
<para>The following options are understood:</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>DUIDType=</varname></term>
|
||||
<term><varname>DUIDRawData=</varname></term>
|
||||
<listitem><para>As in the [DHCPv4] section.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
|
@ -1983,6 +1983,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<term><varname>UseNTP=</varname></term>
|
||||
<term><varname>UseHostname=</varname></term>
|
||||
<term><varname>UseDomains=</varname></term>
|
||||
<term><varname>IAID=</varname></term>
|
||||
<term><varname>DUIDType=</varname></term>
|
||||
<term><varname>DUIDRawData=</varname></term>
|
||||
<listitem>
|
||||
<para>As in the [DHCPv4] section.</para>
|
||||
</listitem>
|
||||
|
@ -3,20 +3,11 @@
|
||||
Copyright © 2014 Vinay Kulkarni <kulkarniv@vmware.com>
|
||||
***/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "def.h"
|
||||
#include "dhcp-identifier.h"
|
||||
#include "extract-word.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-speed-meter.h"
|
||||
#include "networkd-dhcp4.h"
|
||||
#include "string-table.h"
|
||||
|
||||
int manager_parse_config_file(Manager *m) {
|
||||
int r;
|
||||
@ -45,147 +36,3 @@ int manager_parse_config_file(Manager *m) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
|
||||
[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);
|
||||
|
||||
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) {
|
||||
|
||||
_cleanup_free_ char *type_string = NULL;
|
||||
const char *p = rvalue;
|
||||
DUID *duid = data;
|
||||
DUIDType type;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(duid);
|
||||
|
||||
r = extract_first_word(&p, &type_string, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Failed to extract DUID type from '%s', ignoring.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = duid_type_from_string(type_string);
|
||||
if (type < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, type,
|
||||
"Failed to parse DUID type '%s', ignoring.", type_string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isempty(p)) {
|
||||
usec_t u;
|
||||
|
||||
if (type != DUID_TYPE_LLT) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_timestamp(p, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse timestamp, ignoring: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
duid->llt_time = u;
|
||||
}
|
||||
|
||||
duid->type = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
DUID *ret = data;
|
||||
uint8_t raw_data[MAX_DUID_LEN];
|
||||
unsigned count = 0;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(ret);
|
||||
|
||||
/* RawData contains DUID in format "NN:NN:NN..." */
|
||||
for (const char *p = rvalue;;) {
|
||||
int n1, n2, len, r;
|
||||
uint32_t byte;
|
||||
_cleanup_free_ char *cbyte = NULL;
|
||||
|
||||
r = extract_first_word(&p, &cbyte, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (count >= MAX_DUID_LEN) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = strlen(cbyte);
|
||||
if (!IN_SET(len, 1, 2)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
|
||||
return 0;
|
||||
}
|
||||
n1 = unhexchar(cbyte[0]);
|
||||
if (len == 2)
|
||||
n2 = unhexchar(cbyte[1]);
|
||||
else
|
||||
n2 = 0;
|
||||
|
||||
if (n1 < 0 || n2 < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
|
||||
raw_data[count++] = byte;
|
||||
}
|
||||
|
||||
assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
|
||||
memcpy(ret->raw_data, raw_data, count);
|
||||
ret->raw_data_len = count;
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,6 +12,3 @@ typedef struct Manager Manager;
|
||||
int manager_parse_config_file(Manager *m);
|
||||
|
||||
const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);
|
||||
|
@ -4,9 +4,11 @@
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include "bus-error.h"
|
||||
#include "dhcp-identifier.h"
|
||||
#include "dhcp-internal.h"
|
||||
#include "dhcp6-internal.h"
|
||||
#include "escape.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-dhcp-common.h"
|
||||
#include "networkd-link.h"
|
||||
@ -61,31 +63,75 @@ void network_adjust_dhcp(Network *network) {
|
||||
network_adjust_dhcp4(network);
|
||||
}
|
||||
|
||||
static struct DUID fallback_duid = { .type = DUID_TYPE_EN };
|
||||
DUID* link_get_duid(Link *link) {
|
||||
if (link->network->duid.type != _DUID_TYPE_INVALID)
|
||||
return &link->network->duid;
|
||||
else if (link->hw_addr.length == 0 && IN_SET(link->manager->duid.type, DUID_TYPE_LLT, DUID_TYPE_LL))
|
||||
static bool duid_needs_product_uuid(const DUID *duid) {
|
||||
assert(duid);
|
||||
|
||||
return duid->type == DUID_TYPE_UUID && duid->raw_data_len == 0;
|
||||
}
|
||||
|
||||
static const struct DUID fallback_duid = { .type = DUID_TYPE_EN };
|
||||
|
||||
const DUID *link_get_duid(Link *link, int family) {
|
||||
const DUID *duid;
|
||||
|
||||
assert(link);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
|
||||
if (link->network) {
|
||||
duid = family == AF_INET ? &link->network->dhcp_duid : &link->network->dhcp6_duid;
|
||||
if (duid->type != _DUID_TYPE_INVALID) {
|
||||
if (duid_needs_product_uuid(duid))
|
||||
return &link->manager->duid_product_uuid;
|
||||
else
|
||||
return duid;
|
||||
}
|
||||
}
|
||||
|
||||
duid = family == AF_INET ? &link->manager->dhcp_duid : &link->manager->dhcp6_duid;
|
||||
if (link->hw_addr.length == 0 && IN_SET(duid->type, DUID_TYPE_LLT, DUID_TYPE_LL))
|
||||
/* Fallback to DUID that works without MAC address.
|
||||
* This is useful for tunnel devices without MAC address. */
|
||||
return &fallback_duid;
|
||||
else
|
||||
return &link->manager->duid;
|
||||
|
||||
return duid;
|
||||
}
|
||||
|
||||
static int duid_set_uuid(DUID *duid, sd_id128_t uuid) {
|
||||
assert(duid);
|
||||
static int link_configure_and_start_dhcp_delayed(Link *link) {
|
||||
int r;
|
||||
|
||||
if (duid->raw_data_len > 0)
|
||||
assert(link);
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return 0;
|
||||
|
||||
if (duid->type != DUID_TYPE_UUID)
|
||||
return -EINVAL;
|
||||
if (!link->dhcp_client) {
|
||||
r = dhcp4_configure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
memcpy(&duid->raw_data, &uuid, sizeof(sd_id128_t));
|
||||
duid->raw_data_len = sizeof(sd_id128_t);
|
||||
if (!link->dhcp6_client) {
|
||||
r = dhcp6_configure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (!link_has_carrier(link))
|
||||
return 0;
|
||||
|
||||
r = dhcp4_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
|
||||
|
||||
r = ndisc_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
|
||||
|
||||
r = dhcp6_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
|
||||
@ -93,7 +139,6 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
|
||||
const sd_bus_error *e;
|
||||
const void *a;
|
||||
size_t sz;
|
||||
DUID *duid;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
@ -119,56 +164,37 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
|
||||
goto configure;
|
||||
}
|
||||
|
||||
memcpy(&manager->product_uuid, a, sz);
|
||||
while ((duid = set_steal_first(manager->duids_requesting_uuid)))
|
||||
(void) duid_set_uuid(duid, manager->product_uuid);
|
||||
|
||||
manager->duids_requesting_uuid = set_free(manager->duids_requesting_uuid);
|
||||
memcpy(&manager->duid_product_uuid.raw_data, a, sz);
|
||||
manager->duid_product_uuid.raw_data_len = sz;
|
||||
|
||||
configure:
|
||||
while ((link = set_steal_first(manager->links_requesting_uuid))) {
|
||||
link_unref(link);
|
||||
|
||||
r = link_configure(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
|
||||
|
||||
/* To avoid calling GetProductUUID() bus method so frequently, set the flag below
|
||||
* even if the method fails. */
|
||||
manager->has_product_uuid = true;
|
||||
|
||||
while ((link = set_steal_first(manager->links_requesting_uuid))) {
|
||||
r = link_configure_and_start_dhcp_delayed(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
link_unref(link);
|
||||
}
|
||||
|
||||
manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_request_product_uuid(Manager *m, Link *link) {
|
||||
int manager_request_product_uuid(Manager *m) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->has_product_uuid)
|
||||
if (m->product_uuid_requested)
|
||||
return 0;
|
||||
|
||||
log_debug("Requesting product UUID");
|
||||
|
||||
if (link) {
|
||||
DUID *duid;
|
||||
|
||||
assert_se(duid = link_get_duid(link));
|
||||
|
||||
r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
if (r > 0)
|
||||
link_ref(link);
|
||||
|
||||
r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (sd_bus_is_ready(m->bus) <= 0) {
|
||||
log_debug("Not connected to system bus, requesting product UUID later.");
|
||||
return 0;
|
||||
@ -188,70 +214,39 @@ int manager_request_product_uuid(Manager *m, Link *link) {
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to get product UUID: %m");
|
||||
|
||||
m->product_uuid_requested = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_requires_uuid(Link *link) {
|
||||
const DUID *duid;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->network);
|
||||
|
||||
duid = link_get_duid(link);
|
||||
if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
|
||||
return false;
|
||||
|
||||
if (link_dhcp4_enabled(link) && IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
|
||||
return true;
|
||||
|
||||
if (link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int link_configure_duid(Link *link) {
|
||||
int dhcp_configure_duid(Link *link, const DUID *duid) {
|
||||
Manager *m;
|
||||
DUID *duid;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->network);
|
||||
assert(duid);
|
||||
|
||||
m = link->manager;
|
||||
duid = link_get_duid(link);
|
||||
|
||||
if (!link_requires_uuid(link))
|
||||
if (!duid_needs_product_uuid(duid))
|
||||
return 1;
|
||||
|
||||
if (m->has_product_uuid) {
|
||||
(void) duid_set_uuid(duid, m->product_uuid);
|
||||
if (m->has_product_uuid)
|
||||
return 1;
|
||||
|
||||
r = manager_request_product_uuid(m);
|
||||
if (r < 0) {
|
||||
log_link_warning_errno(link, r,
|
||||
"Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!m->links_requesting_uuid) {
|
||||
r = manager_request_product_uuid(m, link);
|
||||
if (r < 0) {
|
||||
if (r == -ENOMEM)
|
||||
return r;
|
||||
|
||||
log_link_warning_errno(link, r,
|
||||
"Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
r = set_put(m->links_requesting_uuid, link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
if (r > 0)
|
||||
link_ref(link);
|
||||
|
||||
r = set_put(m->duids_requesting_uuid, duid);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
if (r > 0)
|
||||
link_ref(link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -523,6 +518,7 @@ int config_parse_iaid(const char *unit,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
uint32_t iaid;
|
||||
int r;
|
||||
@ -531,6 +527,7 @@ int config_parse_iaid(const char *unit,
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(network);
|
||||
assert(IN_SET(ltype, AF_INET, AF_INET6));
|
||||
|
||||
r = safe_atou32(rvalue, &iaid);
|
||||
if (r < 0) {
|
||||
@ -539,8 +536,21 @@ int config_parse_iaid(const char *unit,
|
||||
return 0;
|
||||
}
|
||||
|
||||
network->iaid = iaid;
|
||||
network->iaid_set = true;
|
||||
if (ltype == AF_INET) {
|
||||
network->dhcp_iaid = iaid;
|
||||
network->dhcp_iaid_set = true;
|
||||
if (!network->dhcp6_iaid_set_explicitly) {
|
||||
/* Backward compatibility. Previously, IAID is shared by DHCP4 and DHCP6.
|
||||
* If DHCP6 IAID is not specified explicitly, then use DHCP4 IAID for DHCP6. */
|
||||
network->dhcp6_iaid = iaid;
|
||||
network->dhcp6_iaid_set = true;
|
||||
}
|
||||
} else {
|
||||
assert(ltype == AF_INET6);
|
||||
network->dhcp6_iaid = iaid;
|
||||
network->dhcp6_iaid_set = true;
|
||||
network->dhcp6_iaid_set_explicitly = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -924,3 +934,260 @@ static const char * const dhcp_option_data_type_table[_DHCP_OPTION_DATA_MAX] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(dhcp_option_data_type, DHCPOptionDataType);
|
||||
|
||||
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
|
||||
[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);
|
||||
|
||||
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) {
|
||||
|
||||
_cleanup_free_ char *type_string = NULL;
|
||||
const char *p = rvalue;
|
||||
bool force = ltype;
|
||||
DUID *duid = data;
|
||||
DUIDType type;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(duid);
|
||||
|
||||
if (!force && duid->set)
|
||||
return 0;
|
||||
|
||||
r = extract_first_word(&p, &type_string, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Failed to extract DUID type from '%s', ignoring.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = duid_type_from_string(type_string);
|
||||
if (type < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, type,
|
||||
"Failed to parse DUID type '%s', ignoring.", type_string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isempty(p)) {
|
||||
usec_t u;
|
||||
|
||||
if (type != DUID_TYPE_LLT) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_timestamp(p, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse timestamp, ignoring: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
duid->llt_time = u;
|
||||
}
|
||||
|
||||
duid->type = type;
|
||||
duid->set = force;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_manager_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) {
|
||||
|
||||
Manager *manager = userdata;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
/* For backward compatibility. Setting both DHCP4 and DHCP6 DUID if they are not specified explicitly. */
|
||||
|
||||
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp6_duid, manager);
|
||||
}
|
||||
|
||||
int config_parse_network_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) {
|
||||
|
||||
Network *network = userdata;
|
||||
int r;
|
||||
|
||||
assert(network);
|
||||
|
||||
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* For backward compatibility, also set DHCP6 DUID if not specified explicitly. */
|
||||
return config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &network->dhcp6_duid, network);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
uint8_t raw_data[MAX_DUID_LEN];
|
||||
unsigned count = 0;
|
||||
bool force = ltype;
|
||||
DUID *duid = data;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(duid);
|
||||
|
||||
if (!force && duid->set)
|
||||
return 0;
|
||||
|
||||
/* RawData contains DUID in format "NN:NN:NN..." */
|
||||
for (const char *p = rvalue;;) {
|
||||
int n1, n2, len, r;
|
||||
uint32_t byte;
|
||||
_cleanup_free_ char *cbyte = NULL;
|
||||
|
||||
r = extract_first_word(&p, &cbyte, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (count >= MAX_DUID_LEN) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = strlen(cbyte);
|
||||
if (!IN_SET(len, 1, 2)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
|
||||
return 0;
|
||||
}
|
||||
n1 = unhexchar(cbyte[0]);
|
||||
if (len == 2)
|
||||
n2 = unhexchar(cbyte[1]);
|
||||
else
|
||||
n2 = 0;
|
||||
|
||||
if (n1 < 0 || n2 < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
|
||||
raw_data[count++] = byte;
|
||||
}
|
||||
|
||||
assert_cc(sizeof(raw_data) == sizeof(duid->raw_data));
|
||||
memcpy(duid->raw_data, raw_data, count);
|
||||
duid->raw_data_len = count;
|
||||
duid->set = force;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_manager_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) {
|
||||
|
||||
Manager *manager = userdata;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
/* For backward compatibility. Setting both DHCP4 and DHCP6 DUID if they are not specified explicitly. */
|
||||
|
||||
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp6_duid, manager);
|
||||
}
|
||||
|
||||
int config_parse_network_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) {
|
||||
|
||||
Network *network = userdata;
|
||||
int r;
|
||||
|
||||
assert(network);
|
||||
|
||||
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* For backward compatibility, also set DHCP6 DUID if not specified explicitly. */
|
||||
return config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &network->dhcp6_duid, network);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "dhcp-identifier.h"
|
||||
#include "time-util.h"
|
||||
@ -37,6 +39,7 @@ typedef struct DUID {
|
||||
uint8_t raw_data_len;
|
||||
uint8_t raw_data[MAX_DUID_LEN];
|
||||
usec_t llt_time;
|
||||
bool set;
|
||||
} DUID;
|
||||
|
||||
bool link_dhcp_enabled(Link *link, int family);
|
||||
@ -49,9 +52,16 @@ static inline bool link_dhcp6_enabled(Link *link) {
|
||||
|
||||
void network_adjust_dhcp(Network *network);
|
||||
|
||||
DUID* link_get_duid(Link *link);
|
||||
int link_configure_duid(Link *link);
|
||||
int manager_request_product_uuid(Manager *m, Link *link);
|
||||
const DUID *link_get_duid(Link *link, int family);
|
||||
static inline const DUID *link_get_dhcp4_duid(Link *link) {
|
||||
return link_get_duid(link, AF_INET);
|
||||
}
|
||||
static inline const DUID *link_get_dhcp6_duid(Link *link) {
|
||||
return link_get_duid(link, AF_INET6);
|
||||
}
|
||||
|
||||
int dhcp_configure_duid(Link *link, const DUID *duid);
|
||||
int manager_request_product_uuid(Manager *m);
|
||||
|
||||
const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
|
||||
DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
|
||||
@ -69,3 +79,9 @@ CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_or_vendor_class);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_manager_duid_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_network_duid_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_manager_duid_rawdata);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_network_duid_rawdata);
|
||||
|
@ -1225,17 +1225,17 @@ static int dhcp4_set_client_identifier(Link *link) {
|
||||
switch (link->network->dhcp_client_identifier) {
|
||||
case DHCP_CLIENT_ID_DUID: {
|
||||
/* If configured, apply user specified DUID and IAID */
|
||||
const DUID *duid = link_get_duid(link);
|
||||
const DUID *duid = link_get_dhcp4_duid(link);
|
||||
|
||||
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
|
||||
r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client,
|
||||
link->network->iaid_set,
|
||||
link->network->iaid,
|
||||
link->network->dhcp_iaid_set,
|
||||
link->network->dhcp_iaid,
|
||||
duid->llt_time);
|
||||
else
|
||||
r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
|
||||
link->network->iaid_set,
|
||||
link->network->iaid,
|
||||
link->network->dhcp_iaid_set,
|
||||
link->network->dhcp_iaid,
|
||||
duid->type,
|
||||
duid->raw_data_len > 0 ? duid->raw_data : NULL,
|
||||
duid->raw_data_len);
|
||||
@ -1245,7 +1245,7 @@ static int dhcp4_set_client_identifier(Link *link) {
|
||||
}
|
||||
case DHCP_CLIENT_ID_DUID_ONLY: {
|
||||
/* If configured, apply user specified DUID */
|
||||
const DUID *duid = link_get_duid(link);
|
||||
const DUID *duid = link_get_dhcp4_duid(link);
|
||||
|
||||
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
|
||||
r = sd_dhcp_client_set_duid_llt(link->dhcp_client,
|
||||
@ -1284,6 +1284,15 @@ static int dhcp4_set_client_identifier(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_configure_duid(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
|
||||
return 1;
|
||||
|
||||
return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
|
||||
}
|
||||
|
||||
static int dhcp4_set_request_address(Link *link) {
|
||||
Address *a;
|
||||
|
||||
@ -1323,6 +1332,10 @@ int dhcp4_configure(Link *link) {
|
||||
if (link->dhcp_client)
|
||||
return -EBUSY; /* Already configured. */
|
||||
|
||||
r = dhcp4_configure_duid(link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
|
||||
@ -1505,6 +1518,20 @@ int dhcp4_update_mac(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp4_start(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link->dhcp_client)
|
||||
return 0;
|
||||
|
||||
if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Acquiring DHCPv4 lease");
|
||||
|
||||
return sd_dhcp_client_start(link->dhcp_client);
|
||||
}
|
||||
|
||||
int config_parse_dhcp_max_attempts(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
@ -20,6 +20,7 @@ typedef enum DHCPClientIdentifier {
|
||||
void network_adjust_dhcp4(Network *network);
|
||||
int dhcp4_configure(Link *link);
|
||||
int dhcp4_update_mac(Link *link);
|
||||
int dhcp4_start(Link *link);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address);
|
||||
|
@ -1354,6 +1354,31 @@ int dhcp6_request_address(Link *link, int ir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_start(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link->dhcp6_client)
|
||||
return 0;
|
||||
|
||||
if (!link_dhcp6_enabled(link))
|
||||
return 0;
|
||||
|
||||
if (link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_NO)
|
||||
return 0;
|
||||
|
||||
if (!in6_addr_is_link_local(&link->ipv6ll_address)) {
|
||||
log_link_debug(link, "IPv6 link-local address is not set, delaying to start DHCPv6 client.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sd_dhcp6_client_is_running(link->dhcp6_client) > 0)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Acquiring DHCPv6 lease");
|
||||
|
||||
return dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
|
||||
}
|
||||
|
||||
int dhcp6_request_prefix_delegation(Link *link) {
|
||||
Link *l;
|
||||
|
||||
@ -1488,13 +1513,13 @@ static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->network->iaid_set) {
|
||||
r = sd_dhcp6_client_set_iaid(client, link->network->iaid);
|
||||
if (link->network->dhcp6_iaid_set) {
|
||||
r = sd_dhcp6_client_set_iaid(client, link->network->dhcp6_iaid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
duid = link_get_duid(link);
|
||||
duid = link_get_dhcp6_duid(link);
|
||||
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
|
||||
r = sd_dhcp6_client_set_duid_llt(client, duid->llt_time);
|
||||
else
|
||||
@ -1524,6 +1549,10 @@ int dhcp6_configure(Link *link) {
|
||||
if (link->dhcp6_client)
|
||||
return -EBUSY;
|
||||
|
||||
r = dhcp_configure_duid(link, link_get_dhcp6_duid(link));
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = sd_dhcp6_client_new(&client);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
|
@ -31,6 +31,7 @@ bool link_dhcp6_pd_is_enabled(Link *link);
|
||||
int dhcp6_pd_remove(Link *link);
|
||||
int dhcp6_configure(Link *link);
|
||||
int dhcp6_update_mac(Link *link);
|
||||
int dhcp6_start(Link *link);
|
||||
int dhcp6_request_address(Link *link, int ir);
|
||||
int dhcp6_request_prefix_delegation(Link *link);
|
||||
|
||||
|
@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
||||
#include <stddef.h>
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "networkd-dhcp-common.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-route.h"
|
||||
%}
|
||||
@ -25,5 +26,10 @@ Network.SpeedMeterIntervalSec, config_parse_sec,
|
||||
Network.ManageForeignRoutingPolicyRules, config_parse_bool, 0, offsetof(Manager, manage_foreign_rules)
|
||||
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
||||
Network.RouteTable, config_parse_route_table_names, 0, 0
|
||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
||||
DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp_duid)
|
||||
DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp_duid)
|
||||
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp6_duid)
|
||||
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp6_duid)
|
||||
/* Deprecated */
|
||||
DHCP.DUIDType, config_parse_manager_duid_type, 0, 0
|
||||
DHCP.DUIDRawData, config_parse_manager_duid_rawdata, 0, 0
|
||||
|
@ -1179,14 +1179,6 @@ static int link_acquire_ipv6_conf(Link *link) {
|
||||
|
||||
assert(link);
|
||||
|
||||
if (link->ndisc) {
|
||||
log_link_debug(link, "Discovering IPv6 routers");
|
||||
|
||||
r = sd_ndisc_start(link->ndisc);
|
||||
if (r < 0 && r != -EBUSY)
|
||||
return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
|
||||
}
|
||||
|
||||
if (link->radv) {
|
||||
assert(link->radv);
|
||||
assert(in6_addr_is_link_local(&link->ipv6ll_address));
|
||||
@ -1202,18 +1194,13 @@ static int link_acquire_ipv6_conf(Link *link) {
|
||||
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
|
||||
}
|
||||
|
||||
if (link_dhcp6_enabled(link) && IN_SET(link->network->dhcp6_without_ra,
|
||||
DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST,
|
||||
DHCP6_CLIENT_START_MODE_SOLICIT)) {
|
||||
assert(link->dhcp6_client);
|
||||
assert(in6_addr_is_link_local(&link->ipv6ll_address));
|
||||
r = ndisc_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
|
||||
|
||||
r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
|
||||
if (r < 0 && r != -EBUSY)
|
||||
return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
|
||||
else
|
||||
log_link_debug(link, "Acquiring DHCPv6 lease");
|
||||
}
|
||||
r = dhcp6_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
|
||||
|
||||
r = dhcp6_request_prefix_delegation(link);
|
||||
if (r < 0)
|
||||
@ -1230,11 +1217,9 @@ static int link_acquire_ipv4_conf(Link *link) {
|
||||
assert(link->manager->event);
|
||||
|
||||
if (link->dhcp_client) {
|
||||
log_link_debug(link, "Acquiring DHCPv4 lease");
|
||||
|
||||
r = sd_dhcp_client_start(link->dhcp_client);
|
||||
r = dhcp4_start(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
|
||||
return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
|
||||
|
||||
} else if (link->ipv4ll) {
|
||||
log_link_debug(link, "Acquiring IPv4 link-local address");
|
||||
@ -2254,12 +2239,6 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
|
||||
link_set_state(link, LINK_STATE_INITIALIZED);
|
||||
link->activated = false;
|
||||
|
||||
/* link_configure_duid() returns 0 if it requests product UUID. In that case,
|
||||
* link_configure() is called later asynchronously. */
|
||||
r = link_configure_duid(link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = link_configure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2374,12 +2353,6 @@ static int link_initialized_and_synced(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* link_configure_duid() returns 0 if it requests product UUID. In that case,
|
||||
* link_configure() is called later asynchronously. */
|
||||
r = link_configure_duid(link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = link_configure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -100,8 +100,8 @@ static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *r
|
||||
(void) manager_set_hostname(m, m->dynamic_hostname);
|
||||
if (m->dynamic_timezone)
|
||||
(void) manager_set_timezone(m, m->dynamic_timezone);
|
||||
if (m->links_requesting_uuid)
|
||||
(void) manager_request_product_uuid(m, NULL);
|
||||
if (!set_isempty(m->links_requesting_uuid))
|
||||
(void) manager_request_product_uuid(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -382,6 +382,9 @@ int manager_new(Manager **ret) {
|
||||
.manage_foreign_routes = true,
|
||||
.manage_foreign_rules = true,
|
||||
.ethtool_fd = -1,
|
||||
.dhcp_duid.type = DUID_TYPE_EN,
|
||||
.dhcp6_duid.type = DUID_TYPE_EN,
|
||||
.duid_product_uuid.type = DUID_TYPE_UUID,
|
||||
};
|
||||
|
||||
m->state_file = strdup("/run/systemd/netif/state");
|
||||
@ -427,8 +430,6 @@ int manager_new(Manager **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m->duid.type = DUID_TYPE_EN;
|
||||
|
||||
*ret = TAKE_PTR(m);
|
||||
|
||||
return 0;
|
||||
@ -452,7 +453,6 @@ Manager* manager_free(Manager *m) {
|
||||
m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
|
||||
m->links = hashmap_free_with_destructor(m->links, link_unref);
|
||||
|
||||
m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
|
||||
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
|
||||
|
||||
m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
|
||||
|
@ -52,11 +52,12 @@ struct Manager {
|
||||
|
||||
usec_t network_dirs_ts_usec;
|
||||
|
||||
DUID duid;
|
||||
sd_id128_t product_uuid;
|
||||
DUID dhcp_duid;
|
||||
DUID dhcp6_duid;
|
||||
DUID duid_product_uuid;
|
||||
bool has_product_uuid;
|
||||
bool product_uuid_requested;
|
||||
Set *links_requesting_uuid;
|
||||
Set *duids_requesting_uuid;
|
||||
|
||||
char* dynamic_hostname;
|
||||
char* dynamic_timezone;
|
||||
|
@ -1341,6 +1341,17 @@ int ndisc_configure(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ndisc_start(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link->ndisc || !link->dhcp6_client)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Discovering IPv6 routers");
|
||||
|
||||
return sd_ndisc_start(link->ndisc);
|
||||
}
|
||||
|
||||
void ndisc_vacuum(Link *link) {
|
||||
NDiscRDNSS *r;
|
||||
NDiscDNSSL *d;
|
||||
|
@ -73,6 +73,7 @@ bool link_ipv6_accept_ra_enabled(Link *link);
|
||||
void network_adjust_ipv6_accept_ra(Network *network);
|
||||
|
||||
int ndisc_configure(Link *link);
|
||||
int ndisc_start(Link *link);
|
||||
void ndisc_vacuum(Link *link);
|
||||
void ndisc_flush(Link *link);
|
||||
|
||||
|
@ -10,7 +10,6 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
||||
#include "networkd-address-label.h"
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-can.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "networkd-dhcp-common.h"
|
||||
#include "networkd-dhcp-server.h"
|
||||
#include "networkd-dhcp4.h"
|
||||
@ -213,12 +212,12 @@ DHCPv4.VendorClassIdentifier, config_parse_string,
|
||||
DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0
|
||||
DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
|
||||
DHCPv4.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
|
||||
DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
|
||||
DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
|
||||
DHCPv4.IAID, config_parse_iaid, AF_INET, 0
|
||||
DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0
|
||||
DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
|
||||
DHCPv4.RouteMetric, config_parse_dhcp_route_metric, 0, 0
|
||||
DHCPv4.RouteTable, config_parse_section_route_table, 0, 0
|
||||
DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
|
||||
DHCPv4.IAID, config_parse_iaid, 0, 0
|
||||
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
|
||||
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
|
||||
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
|
||||
@ -244,6 +243,9 @@ DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool,
|
||||
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
|
||||
DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra)
|
||||
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
|
||||
DHCPv6.IAID, config_parse_iaid, AF_INET6, 0
|
||||
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid)
|
||||
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid)
|
||||
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
|
||||
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
|
||||
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
|
||||
@ -483,12 +485,12 @@ DHCP.RequestBroadcast, config_parse_bool,
|
||||
DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
|
||||
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
|
||||
DHCP.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
|
||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
|
||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
|
||||
DHCP.IAID, config_parse_iaid, AF_INET, 0
|
||||
DHCP.DUIDType, config_parse_network_duid_type, 0, 0
|
||||
DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
|
||||
DHCP.RouteMetric, config_parse_dhcp_route_metric, 0, 0
|
||||
DHCP.RouteTable, config_parse_section_route_table, 0, 0
|
||||
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
|
||||
DHCP.IAID, config_parse_iaid, 0, 0
|
||||
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
|
||||
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit)
|
||||
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
|
||||
|
@ -301,7 +301,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
.ignore_carrier_loss = -1,
|
||||
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
|
||||
|
||||
.duid.type = _DUID_TYPE_INVALID,
|
||||
.dhcp_duid.type = _DUID_TYPE_INVALID,
|
||||
.dhcp_critical = -1,
|
||||
.dhcp_use_ntp = true,
|
||||
.dhcp_use_sip = true,
|
||||
@ -321,6 +321,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
.dhcp6_use_hostname = true,
|
||||
.dhcp6_use_ntp = true,
|
||||
.dhcp6_rapid_commit = true,
|
||||
.dhcp6_duid.type = _DUID_TYPE_INVALID,
|
||||
|
||||
.dhcp6_pd = -1,
|
||||
.dhcp6_pd_announce = true,
|
||||
@ -599,10 +600,6 @@ static Network *network_free(Network *network) {
|
||||
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
|
||||
ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
|
||||
|
||||
if (network->manager &&
|
||||
network->manager->duids_requesting_uuid)
|
||||
set_remove(network->manager->duids_requesting_uuid, &network->duid);
|
||||
|
||||
free(network->name);
|
||||
|
||||
free(network->dhcp_server_timezone);
|
||||
|
@ -118,9 +118,9 @@ struct Network {
|
||||
/* DHCP Client Support */
|
||||
AddressFamily dhcp;
|
||||
DHCPClientIdentifier dhcp_client_identifier;
|
||||
DUID duid;
|
||||
uint32_t iaid;
|
||||
bool iaid_set;
|
||||
DUID dhcp_duid;
|
||||
uint32_t dhcp_iaid;
|
||||
bool dhcp_iaid_set;
|
||||
char *dhcp_vendor_class_identifier;
|
||||
char *dhcp_mudurl;
|
||||
char **dhcp_user_class;
|
||||
@ -169,6 +169,10 @@ struct Network {
|
||||
bool dhcp6_rapid_commit;
|
||||
DHCPUseDomains dhcp6_use_domains;
|
||||
bool dhcp6_use_domains_set;
|
||||
uint32_t dhcp6_iaid;
|
||||
bool dhcp6_iaid_set;
|
||||
bool dhcp6_iaid_set_explicitly;
|
||||
DUID dhcp6_duid;
|
||||
uint8_t dhcp6_pd_length;
|
||||
char *dhcp6_mudurl;
|
||||
char **dhcp6_user_class;
|
||||
|
@ -19,6 +19,10 @@
|
||||
#ManageForeignRoutes=yes
|
||||
#RouteTable=
|
||||
|
||||
[DHCP]
|
||||
[DHCPv4]
|
||||
#DUIDType=vendor
|
||||
#DUIDRawData=
|
||||
|
||||
[DHCPv6]
|
||||
#DUIDType=vendor
|
||||
#DUIDRawData=
|
||||
|
@ -141,6 +141,9 @@ UserClass=
|
||||
VendorClass=
|
||||
SendVendorOption=
|
||||
RouteMetric=
|
||||
IAID=
|
||||
DUIDType=
|
||||
DUIDRawData=
|
||||
[DHCPv6PrefixDelegation]
|
||||
SubnetId=
|
||||
Announce=
|
||||
|
Loading…
Reference in New Issue
Block a user