dhcp: allow to not send client-id (option 61) in IPv4

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1742
This commit is contained in:
Íñigo Huguet 2023-10-18 08:02:34 +02:00
commit ef6ccc0ee8
12 changed files with 222 additions and 111 deletions

View file

@ -2017,7 +2017,10 @@ _prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con)
}
static GBytes *
_prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes *hwaddr)
_prop_get_ipv4_dhcp_client_id(NMDevice *self,
NMConnection *connection,
GBytes *hwaddr,
gboolean *out_send_client_id)
{
NMSettingIPConfig *s_ip4;
const char *client_id;
@ -2030,6 +2033,8 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes *
GBytes *result;
gs_free char *logstr1 = NULL;
NM_SET_OUT(out_send_client_id, TRUE);
s_ip4 = nm_connection_get_setting_ip4_config(connection);
client_id = nm_setting_ip4_config_get_dhcp_client_id(NM_SETTING_IP4_CONFIG(s_ip4));
@ -2049,6 +2054,12 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes *
return NULL;
}
if (nm_streq(client_id, "none")) {
_LOGD(LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, "ipv4.dhcp-client-id: set to \"none\"");
NM_SET_OUT(out_send_client_id, FALSE);
return NULL;
}
if (nm_streq(client_id, "mac")) {
if (!hwaddr) {
fail_reason = "missing link-layer address";
@ -10707,8 +10718,10 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
const char *const *reject_servers;
const char *hostname;
gboolean hostname_is_fqdn;
gboolean send_client_id;
client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr, &send_client_id);
client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr);
vendor_class_identifier =
_prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip));
reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip, NULL);
@ -10745,6 +10758,7 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
{
.request_broadcast = request_broadcast,
.acd_timeout_msec = _prop_get_ipv4_dad_timeout(self),
.send_client_id = send_client_id,
},
.previous_lease = priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4)].d,
};

View file

@ -162,6 +162,9 @@ typedef struct {
* will always broadcast replies. */
bool request_broadcast : 1;
/* Whether to send or not the client identifier */
bool send_client_id : 1;
} v4;
struct {
/* If set, the DUID from the connection is used; otherwise

View file

@ -120,7 +120,10 @@ add_ip4_config(GString *str,
}
g_string_append(str, CLIENTID_TAG " ");
if (i < l) {
if (l == 0) {
/* An empty value effectively unsets the client-id to avoid sending it */
g_string_append(str, "\"\"");
} else if (i < l) {
/* Unprintable; convert to a hex string */
for (i = 0; i < l; i++) {
if (i > 0)
@ -293,6 +296,7 @@ char *
nm_dhcp_dhclient_create_config(const char *interface,
int addr_family,
GBytes *client_id,
gboolean send_client_id,
const char *anycast_address,
const char *hostname,
guint32 timeout,
@ -391,8 +395,8 @@ nm_dhcp_dhclient_create_config(const char *interface,
continue;
if (NM_STR_HAS_PREFIX(p, CLIENTID_TAG)) {
/* Override config file "dhcp-client-id" and use one from the connection */
if (client_id)
/* Skip "dhcp-client-id" if the connection has defined a custom one or "none" */
if (client_id || !send_client_id)
continue;
/* Otherwise, capture and return the existing client id */
@ -477,6 +481,8 @@ nm_dhcp_dhclient_create_config(const char *interface,
}
if (addr_family == AF_INET) {
nm_auto_unref_bytes GBytes *client_id_none = NULL;
client_id = send_client_id ? client_id : (client_id_none = g_bytes_new_static("", 0));
add_ip4_config(new_contents, client_id, hostname, use_fqdn, hostname_flags);
add_request(reqs, "rfc3442-classless-static-routes");
add_request(reqs, "ms-classless-static-routes");

View file

@ -12,6 +12,7 @@
char *nm_dhcp_dhclient_create_config(const char *interface,
int addr_family,
GBytes *client_id,
gboolean send_client_id,
const char *anycast_addr,
const char *hostname,
guint32 timeout,

View file

@ -148,56 +148,6 @@ get_dhclient_leasefile(int addr_family,
return NULL;
}
static gboolean
merge_dhclient_config(NMDhcpDhclient *self,
int addr_family,
const char *iface,
const char *conf_file,
GBytes *client_id,
const char *anycast_address,
const char *hostname,
guint32 timeout,
gboolean use_fqdn,
NMDhcpHostnameFlags hostname_flags,
const char *mud_url,
const char *const *reject_servers,
const char *orig_path,
GBytes **out_new_client_id,
GError **error)
{
gs_free char *orig = NULL;
gs_free char *new = NULL;
g_return_val_if_fail(iface, FALSE);
g_return_val_if_fail(conf_file, FALSE);
if (orig_path && g_file_test(orig_path, G_FILE_TEST_EXISTS)) {
GError *read_error = NULL;
if (!g_file_get_contents(orig_path, &orig, NULL, &read_error)) {
_LOGW("error reading dhclient configuration %s: %s", orig_path, read_error->message);
g_error_free(read_error);
}
}
new = nm_dhcp_dhclient_create_config(iface,
addr_family,
client_id,
anycast_address,
hostname,
timeout,
use_fqdn,
hostname_flags,
mud_url,
reject_servers,
orig_path,
orig,
out_new_client_id);
nm_assert(new);
return g_file_set_contents(conf_file, new, -1, error);
}
static char *
find_existing_config(NMDhcpDhclient *self, int addr_family, const char *iface, const char *uuid)
{
@ -283,6 +233,7 @@ create_dhclient_config(NMDhcpDhclient *self,
const char *iface,
const char *uuid,
GBytes *client_id,
gboolean send_client_id,
const char *anycast_address,
const char *hostname,
guint32 timeout,
@ -292,44 +243,56 @@ create_dhclient_config(NMDhcpDhclient *self,
const char *const *reject_servers,
GBytes **out_new_client_id)
{
gs_free char *orig = NULL;
char *new = NULL;
GError *error = NULL;
gs_free char *orig_path = NULL;
gs_free char *orig_content = NULL;
char *new_path = NULL;
gs_free char *new_content = NULL;
GError *error = NULL;
g_return_val_if_fail(iface != NULL, NULL);
new = g_strdup_printf(NMSTATEDIR "/dhclient%s-%s.conf",
_addr_family_to_path_part(addr_family),
iface);
new_path = g_strdup_printf(NMSTATEDIR "/dhclient%s-%s.conf",
_addr_family_to_path_part(addr_family),
iface);
_LOGD("creating composite dhclient config %s", new_path);
_LOGD("creating composite dhclient config %s", new);
orig = find_existing_config(self, addr_family, iface, uuid);
if (orig)
_LOGD("merging existing dhclient config %s", orig);
orig_path = find_existing_config(self, addr_family, iface, uuid);
if (orig_path)
_LOGD("merging existing dhclient config %s", orig_path);
else
_LOGD("no existing dhclient configuration to merge");
if (!merge_dhclient_config(self,
addr_family,
iface,
new,
client_id,
anycast_address,
hostname,
timeout,
use_fqdn,
hostname_flags,
mud_url,
reject_servers,
orig,
out_new_client_id,
&error)) {
_LOGW("error creating dhclient configuration: %s", error->message);
g_clear_error(&error);
if (orig_path && g_file_test(orig_path, G_FILE_TEST_EXISTS)) {
if (!g_file_get_contents(orig_path, &orig_content, NULL, &error)) {
_LOGW("error reading dhclient configuration %s: %s", orig_path, error->message);
g_error_free(error);
}
}
return new;
new_content = nm_dhcp_dhclient_create_config(iface,
addr_family,
client_id,
send_client_id,
anycast_address,
hostname,
timeout,
use_fqdn,
hostname_flags,
mud_url,
reject_servers,
orig_path,
orig_content,
out_new_client_id);
nm_assert(new_content);
if (!g_file_set_contents(new_path, new_content, -1, &error)) {
_LOGW("error creating dhclient configuration: %s", error->message);
g_error_free(error);
g_free(new_path);
return NULL;
}
return new_path;
}
static gboolean
@ -547,11 +510,14 @@ ip4_start(NMDhcpClient *client, GError **error)
client_config = nm_dhcp_client_get_config(client);
nm_assert(client_config->addr_family == AF_INET);
priv->conf_file = create_dhclient_config(self,
AF_INET,
client_config->iface,
client_config->uuid,
client_config->client_id,
client_config->v4.send_client_id,
client_config->anycast_address,
client_config->hostname,
client_config->timeout,
@ -584,6 +550,8 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error)
config = nm_dhcp_client_get_config(client);
nm_assert(config->addr_family == AF_INET6);
if (config->v6.iaid_explicit)
_LOGW("dhclient does not support specifying an IAID for DHCPv6, it will be ignored");
@ -592,6 +560,7 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error)
config->iface,
config->uuid,
NULL,
TRUE,
config->anycast_address,
config->hostname,
config->timeout,

View file

@ -1119,6 +1119,7 @@ nettools_create(NMDhcpNettools *self, GBytes **out_effective_client_id, GError *
gs_unref_bytes GBytes *client_id_new = NULL;
const uint8_t *client_id_arr;
size_t client_id_len;
bool send_client_id;
int r, fd, arp_type, transport;
const NMDhcpClientConfig *client_config;
@ -1150,20 +1151,37 @@ nettools_create(NMDhcpNettools *self, GBytes **out_effective_client_id, GError *
return FALSE;
}
/* Note that we always set a client-id. In particular for infiniband that is necessary,
* see https://tools.ietf.org/html/rfc4390#section-2.1 . */
client_id = client_config->client_id;
if (!client_id) {
client_id = client_config->client_id;
send_client_id = client_config->v4.send_client_id;
if (!send_client_id && transport == N_DHCP4_TRANSPORT_INFINIBAND) {
/* Client-id is mandatory for infiniband: https://tools.ietf.org/html/rfc4390#section-2.1 */
_LOGI("ipv4.client-id is set to \"none\", but it's mandatory for Infiniband. Setting a "
"default one.");
send_client_id = TRUE;
}
if (send_client_id && !client_id) {
client_id_new = nm_utils_dhcp_client_id_mac(arp_type, hwaddr_arr, hwaddr_len);
client_id = client_id_new;
}
if (!(client_id_arr = g_bytes_get_data(client_id, &client_id_len)) || client_id_len < 2) {
/* invalid client-ids are not expected. */
nm_assert_not_reached();
g_return_val_if_fail(client_id || !send_client_id, FALSE);
nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "no valid IPv4 client-id");
return FALSE;
if (send_client_id) {
client_id_arr = g_bytes_get_data(client_id, &client_id_len);
client_id_len = NM_MIN(client_id_len, 1 + _NM_MAX_CLIENT_ID_LEN);
if (!client_id_arr || client_id_len < 2) {
/* invalid client-ids are not expected. */
nm_assert_not_reached();
nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "no valid IPv4 client-id");
return FALSE;
}
} else {
client_id_arr = NULL;
/* This will unset the client-id and prevent it from being sent */
client_id_len = 0;
}
r = n_dhcp4_client_config_new(&config);
@ -1177,9 +1195,7 @@ nettools_create(NMDhcpNettools *self, GBytes **out_effective_client_id, GError *
n_dhcp4_client_config_set_mac(config, hwaddr_arr, hwaddr_len);
n_dhcp4_client_config_set_broadcast_mac(config, bcast_hwaddr_arr, bcast_hwaddr_len);
n_dhcp4_client_config_set_request_broadcast(config, client_config->v4.request_broadcast);
r = n_dhcp4_client_config_set_client_id(config,
client_id_arr,
NM_MIN(client_id_len, 1 + _NM_MAX_CLIENT_ID_LEN));
r = n_dhcp4_client_config_set_client_id(config, client_id_arr, client_id_len);
if (r) {
set_error_nettools(error, r, "failed to set client-id");
return FALSE;

View file

@ -36,11 +36,14 @@ test_config(const char *orig,
const char *anycast_addr,
const char *mud_url)
{
gs_free char *new = NULL;
gs_unref_bytes GBytes *client_id = NULL;
gs_unref_bytes GBytes *new_client_id = NULL;
gs_free char *new = NULL;
gs_unref_bytes GBytes *client_id = NULL;
gs_unref_bytes GBytes *new_client_id = NULL;
gboolean send_client_id = TRUE;
if (dhcp_client_id) {
if (nm_streq0(dhcp_client_id, "none")) {
send_client_id = FALSE;
} else if (dhcp_client_id) {
client_id = nm_dhcp_utils_client_id_string_to_bytes(dhcp_client_id);
g_assert(client_id);
}
@ -48,6 +51,7 @@ test_config(const char *orig,
new = nm_dhcp_dhclient_create_config(iface,
addr_family,
client_id,
send_client_id,
anycast_addr,
hostname,
timeout,
@ -502,6 +506,90 @@ test_existing_ascii_client_id(void)
NULL,
NULL);
}
/*****************************************************************************/
static const char *none_client_id_orig = "send dhcp-client-identifier 10:30:04:20:7A:08;\n";
static const char *none_client_id_expected =
"# Created by NetworkManager\n"
"# Merged from /path/to/dhclient.conf\n"
"\n"
"send dhcp-client-identifier \"\"; # added by NetworkManager\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
"option wpad code 252 = string;\n"
"\n"
"also request rfc3442-classless-static-routes;\n"
"also request ms-classless-static-routes;\n"
"also request static-routes;\n"
"also request wpad;\n"
"also request ntp-servers;\n"
"also request root-path;\n"
"\n";
static void
test_none_client_id(void)
{
const char *connection_client_id = "none";
gs_unref_bytes GBytes *expected_client_id = NULL;
test_config(none_client_id_orig,
none_client_id_expected,
AF_INET,
NULL,
0,
FALSE,
NM_DHCP_HOSTNAME_FLAG_NONE,
connection_client_id,
expected_client_id,
"eth0",
NULL,
NULL);
}
/*****************************************************************************/
static const char *missing_client_id_orig = "";
static const char *missing_client_id_expected =
"# Created by NetworkManager\n"
"# Merged from /path/to/dhclient.conf\n"
"\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
"option wpad code 252 = string;\n"
"\n"
"also request rfc3442-classless-static-routes;\n"
"also request ms-classless-static-routes;\n"
"also request static-routes;\n"
"also request wpad;\n"
"also request ntp-servers;\n"
"also request root-path;\n"
"\n";
static void
test_missing_client_id(void)
{
const char *connection_client_id = NULL;
gs_unref_bytes GBytes *expected_client_id = NULL;
test_config(missing_client_id_orig,
missing_client_id_expected,
AF_INET,
NULL,
0,
FALSE,
NM_DHCP_HOSTNAME_FLAG_NONE,
connection_client_id,
expected_client_id,
"eth0",
NULL,
NULL);
}
/*****************************************************************************/
static const char *fqdn_expected =
@ -1364,6 +1452,8 @@ main(int argc, char **argv)
g_test_add_func("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
g_test_add_func("/dhcp/dhclient/existing-client-id", test_existing_escaped_client_id);
g_test_add_func("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
g_test_add_func("/dhcp/dhclient/none-client-id", test_none_client_id);
g_test_add_func("/dhcp/dhclient/missing-client-id", test_missing_client_id);
g_test_add_func("/dhcp/dhclient/fqdn", test_fqdn);
g_test_add_func("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);
g_test_add_func("/dhcp/dhclient/override_hostname", test_override_hostname);

View file

@ -894,9 +894,19 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass)
* stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a
* per-device key.
*
* If unset, a globally configured default is used. If still unset, the default
* depends on the DHCP plugin.
* The special value "none" prevents any client identifier from being sent. Note that
* this is normally not recommended.
*
* If unset, a globally configured default from NetworkManager.conf is used. If still
* unset, the default depends on the DHCP plugin. The internal dhcp client will
* generate a default value and the dhclient plugin will try to use one from its
* config file if present, or won't sent any client-id otherwise.
**/
/* ---nmcli---
* property: dhcp-client-id
* special-values: mac, perm-mac, duid, ipv6-duid, stable, none
* ---end---
*/
/* ---ifcfg-rh---
* property: dhcp-client-id
* variable: DHCP_CLIENT_ID(+)

View file

@ -161,7 +161,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in decreasing priority, meaning the first address will be the primary address.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_AUTO_ROUTE_EXT_GW N_("VPN connections will default to add the route automatically unless this setting is set to FALSE. For other connection types, adding such an automatic route is currently not supported and setting this to TRUE has no effect.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Maximum timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. The property is currently implemented only for IPv4. A zero value means that no duplicate address detection is performed, -1 means the default value (either the value configured globally in NetworkManger.conf or zero). A value greater than zero is a timeout in milliseconds. Note that the time intervals are subject to randomization as per RFC 5227 and so the actual duration can be between half and the full time specified in this property.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. The special value \"none\" prevents any client identifier from being sent. Note that this is normally not recommended. If unset, a globally configured default from NetworkManager.conf is used. If still unset, the default depends on the DHCP plugin. The internal dhcp client will generate a default value and the dhclient plugin will try to use one from its config file if present, or won't sent any client-id otherwise.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME_FLAGS N_("Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are \"fqdn-serv-update\" (0x1), \"fqdn-encoded\" (0x2) and \"fqdn-no-update\" (0x4). When no FQDN flag is set and \"fqdn-clear-flags\" (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and \"fqdn-clear-flags\" (0x8) is not set, the standard FQDN flags are set in the request: \"fqdn-serv-update\" (0x1), \"fqdn-encoded\" (0x2) for IPv4 and \"fqdn-serv-update\" (0x1) for IPv6. When this property is set to the default value \"none\" (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also \"none\" (0x0), then the standard FQDN flags described above are sent in the DHCP requests.")

View file

@ -543,12 +543,14 @@ static int n_dhcp4_c_connection_new_message(NDhcp4CConnection *connection,
if (r)
return r;
r = n_dhcp4_outgoing_append(message,
N_DHCP4_OPTION_CLIENT_IDENTIFIER,
connection->client_config->client_id,
connection->client_config->n_client_id);
if (r)
return r;
if (connection->client_config->n_client_id > 0) {
r = n_dhcp4_outgoing_append(message,
N_DHCP4_OPTION_CLIENT_IDENTIFIER,
connection->client_config->client_id,
connection->client_config->n_client_id);
if (r)
return r;
}
switch (message_type) {
case N_DHCP4_MESSAGE_DISCOVER:

View file

@ -403,7 +403,7 @@ _c_public_ int n_dhcp4_client_new(NDhcp4Client **clientp, NDhcp4ClientConfig *co
return N_DHCP4_E_INVALID_TRANSPORT;
}
if (config->n_client_id < 1)
if (config->n_client_id != 0 && config->n_client_id < 2)
return N_DHCP4_E_INVALID_CLIENT_ID;
}

View file

@ -1256,7 +1256,7 @@
format="boolean"
values="true/yes/on, false/no/off" />
<property name="dhcp-client-id"
nmcli-description="A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string (&apos;aa:bb:cc&apos;) it is interpreted as a binary client ID, in which case the first byte is assumed to be the &apos;type&apos; field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. &apos;01:xx:xx:xx:xx:xx:xx&apos; where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the &apos;type&apos; field is set to 0. The special values &quot;mac&quot; and &quot;perm-mac&quot; are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value &quot;ipv6-duid&quot; uses the DUID from &quot;ipv6.dhcp-duid&quot; property as an RFC4361-compliant client identifier. As IAID it uses &quot;ipv4.dhcp-iaid&quot; and falls back to &quot;ipv6.dhcp-iaid&quot; if unset. The special value &quot;duid&quot; generates a RFC4361-compliant client identifier based on &quot;ipv4.dhcp-iaid&quot; and uses a DUID generated by hashing /etc/machine-id. The special value &quot;stable&quot; is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the &quot;${DEVICE}&quot; or &quot;${MAC}&quot; specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin."
nmcli-description="A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string (&apos;aa:bb:cc&apos;) it is interpreted as a binary client ID, in which case the first byte is assumed to be the &apos;type&apos; field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. &apos;01:xx:xx:xx:xx:xx:xx&apos; where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the &apos;type&apos; field is set to 0. The special values &quot;mac&quot; and &quot;perm-mac&quot; are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value &quot;ipv6-duid&quot; uses the DUID from &quot;ipv6.dhcp-duid&quot; property as an RFC4361-compliant client identifier. As IAID it uses &quot;ipv4.dhcp-iaid&quot; and falls back to &quot;ipv6.dhcp-iaid&quot; if unset. The special value &quot;duid&quot; generates a RFC4361-compliant client identifier based on &quot;ipv4.dhcp-iaid&quot; and uses a DUID generated by hashing /etc/machine-id. The special value &quot;stable&quot; is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the &quot;${DEVICE}&quot; or &quot;${MAC}&quot; specifier to get a per-device key. The special value &quot;none&quot; prevents any client identifier from being sent. Note that this is normally not recommended. If unset, a globally configured default from NetworkManager.conf is used. If still unset, the default depends on the DHCP plugin. The internal dhcp client will generate a default value and the dhclient plugin will try to use one from its config file if present, or won&apos;t sent any client-id otherwise."
format="string" />
<property name="dhcp-iaid"
nmcli-description="A string containing the &quot;Identity Association Identifier&quot; (IAID) used by the DHCP client. The string can be a 32-bit number (either decimal, hexadecimal or as colon separated hexadecimal numbers). Alternatively it can be set to the special values &quot;mac&quot;, &quot;perm-mac&quot;, &quot;ifname&quot; or &quot;stable&quot;. When set to &quot;mac&quot; (or &quot;perm-mac&quot;), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to &quot;ifname&quot;, the IAID is computed by hashing the interface name. The special value &quot;stable&quot; can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be &quot;ifname&quot;. For DHCPv4, the IAID is only used with &quot;ipv4.dhcp-client-id&quot; values &quot;duid&quot; and &quot;ipv6-duid&quot; to generate the client-id. For DHCPv6, note that at the moment this property is only supported by the &quot;internal&quot; DHCPv6 plugin. The &quot;dhclient&quot; DHCPv6 plugin always derives the IAID from the MAC address. The actually used DHCPv6 IAID for a currently activated interface is exposed in the lease information of the device."