mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
dhcp4: introduce new option 'duid-only' for ClientIdentifier= (#8350)
This makes users can configure DHCPv4 client with ClientIdentifier=duid-only. If set so, then DHCP client sends only DUID as the client identifier. This may not be RFC compliant, but some setups require this. Closes #7828.
This commit is contained in:
parent
6910dceef2
commit
dace710c4a
@ -1236,8 +1236,11 @@
|
||||
<varlistentry>
|
||||
<term><varname>ClientIdentifier=</varname></term>
|
||||
<listitem>
|
||||
<para>The DHCPv4 client identifier to use. Either <literal>mac</literal> to use the MAC address of the link
|
||||
or <literal>duid</literal> (the default, see below) to use an RFC4361-compliant Client ID.</para>
|
||||
<para>The DHCPv4 client identifier to use. Takes one of <literal>mac</literal>, <literal>duid</literal> or <literal>duid-only</literal>.
|
||||
If set to <literal>mac</literal>, the MAC address of the link is used.
|
||||
If set to <literal>duid</literal>, an RFC4361-compliant Client ID, which is the combination of IAID and DUID (see below), is used.
|
||||
If set to <literal>duid-only</literal>, only DUID is used, this may not be RFC compliant, but some setups may require to use this.
|
||||
Defaults to <literal>duid</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -354,9 +354,10 @@ int sd_dhcp_client_set_client_id(
|
||||
* without further modification. Otherwise, if duid_type is supported, DUID
|
||||
* is set based on that type. Otherwise, an error is returned.
|
||||
*/
|
||||
int sd_dhcp_client_set_iaid_duid(
|
||||
static int dhcp_client_set_iaid_duid(
|
||||
sd_dhcp_client *client,
|
||||
uint32_t iaid,
|
||||
bool append_iaid,
|
||||
uint16_t duid_type,
|
||||
const void *duid,
|
||||
size_t duid_len) {
|
||||
@ -377,15 +378,17 @@ int sd_dhcp_client_set_iaid_duid(
|
||||
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->ifindex, 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 (append_iaid) {
|
||||
/* If IAID is not configured, generate it. */
|
||||
if (iaid == 0) {
|
||||
r = dhcp_identifier_set_iaid(client->ifindex, 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 != NULL) {
|
||||
client->client_id.ns.duid.type = htobe16(duid_type);
|
||||
@ -399,7 +402,7 @@ int sd_dhcp_client_set_iaid_duid(
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
client->client_id_len = sizeof(client->client_id.type) + len +
|
||||
sizeof(client->client_id.ns.iaid);
|
||||
(append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
|
||||
|
||||
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
|
||||
log_dhcp_client(client, "Configured IAID+DUID, restarting.");
|
||||
@ -410,6 +413,23 @@ int sd_dhcp_client_set_iaid_duid(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_iaid_duid(
|
||||
sd_dhcp_client *client,
|
||||
uint32_t iaid,
|
||||
uint16_t duid_type,
|
||||
const void *duid,
|
||||
size_t duid_len) {
|
||||
return dhcp_client_set_iaid_duid(client, iaid, true, duid_type, duid, duid_len);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_duid(
|
||||
sd_dhcp_client *client,
|
||||
uint16_t duid_type,
|
||||
const void *duid,
|
||||
size_t duid_len) {
|
||||
return dhcp_client_set_iaid_duid(client, 0, false, duid_type, duid, duid_len);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_hostname(
|
||||
sd_dhcp_client *client,
|
||||
const char *hostname) {
|
||||
|
@ -776,6 +776,18 @@ int dhcp4_configure(Link *link) {
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
case DHCP_CLIENT_ID_DUID_ONLY: {
|
||||
/* If configured, apply user specified DUID */
|
||||
const DUID *duid = link_duid(link);
|
||||
|
||||
r = sd_dhcp_client_set_duid(link->dhcp_client,
|
||||
duid->type,
|
||||
duid->raw_data_len > 0 ? duid->raw_data : NULL,
|
||||
duid->raw_data_len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
case DHCP_CLIENT_ID_MAC:
|
||||
r = sd_dhcp_client_set_client_id(link->dhcp_client,
|
||||
ARPHRD_ETHER,
|
||||
|
@ -3282,6 +3282,17 @@ int link_update(Link *link, sd_netlink_message *m) {
|
||||
return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
|
||||
break;
|
||||
}
|
||||
case DHCP_CLIENT_ID_DUID_ONLY: {
|
||||
const DUID *duid = link_duid(link);
|
||||
|
||||
r = sd_dhcp_client_set_duid(link->dhcp_client,
|
||||
duid->type,
|
||||
duid->raw_data_len > 0 ? duid->raw_data : NULL,
|
||||
duid->raw_data_len);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not update DUID in DHCP client: %m");
|
||||
break;
|
||||
}
|
||||
case DHCP_CLIENT_ID_MAC:
|
||||
r = sd_dhcp_client_set_client_id(link->dhcp_client,
|
||||
ARPHRD_ETHER,
|
||||
|
@ -859,7 +859,8 @@ int config_parse_dhcp(
|
||||
|
||||
static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
|
||||
[DHCP_CLIENT_ID_MAC] = "mac",
|
||||
[DHCP_CLIENT_ID_DUID] = "duid"
|
||||
[DHCP_CLIENT_ID_DUID] = "duid",
|
||||
[DHCP_CLIENT_ID_DUID_ONLY] = "duid-only",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DHCPClientIdentifier);
|
||||
|
@ -49,6 +49,11 @@
|
||||
typedef enum DHCPClientIdentifier {
|
||||
DHCP_CLIENT_ID_MAC,
|
||||
DHCP_CLIENT_ID_DUID,
|
||||
/* The following option may not be good for RFC regarding DHCP (3315 and 4361).
|
||||
* But some setups require this. E.g., Sky Broadband, the second largest provider in the UK
|
||||
* requires the client id to be set to a custom string, reported at
|
||||
* https://github.com/systemd/systemd/issues/7828 */
|
||||
DHCP_CLIENT_ID_DUID_ONLY,
|
||||
_DHCP_CLIENT_ID_MAX,
|
||||
_DHCP_CLIENT_ID_INVALID = -1,
|
||||
} DHCPClientIdentifier;
|
||||
|
@ -132,6 +132,11 @@ int sd_dhcp_client_set_iaid_duid(
|
||||
uint16_t duid_type,
|
||||
const void *duid,
|
||||
size_t duid_len);
|
||||
int sd_dhcp_client_set_duid(
|
||||
sd_dhcp_client *client,
|
||||
uint16_t duid_type,
|
||||
const void *duid,
|
||||
size_t duid_len);
|
||||
int sd_dhcp_client_get_client_id(
|
||||
sd_dhcp_client *client,
|
||||
uint8_t *type,
|
||||
|
Loading…
Reference in New Issue
Block a user