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

Sending a client-id is not mandatory according to RFC2131. It is
mandatory according to RFC4361 that superseedes it.

Some weird DHCP servers conforming RFC2131 can get confused and break
existing DHCP leases if they start receiving a client-id when it was not
being previously received. Users that were using other DHCP client like
dhclient, but want to use NetworkManager's internal DHCP client, can
suffer this problem.

Add "none" as accepted value in ipv4.dhcp-client-id to specify that
client-id must not be sent. Note that this is generally not recommended
unless it's explicitly needed for some reason like the explained above.

Client-id is mandatory in DHCPv6.

This commit allow to set the "none" value and properly parse it in the
NMDhcpClientConfig struct. Next commits will modify the different DHCP
plugins to honor it.
This commit is contained in:
Íñigo Huguet 2023-09-26 12:40:52 +02:00
parent 5b16c128bb
commit f78a18bf16
3 changed files with 24 additions and 2 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

@ -897,6 +897,11 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass)
* If unset, a globally configured default is used. If still unset, the default
* depends on the DHCP plugin.
**/
/* ---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(+)