summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÍñigo Huguet <ihuguet@redhat.com>2023-09-27 15:49:41 +0200
committerÍñigo Huguet <ihuguet@redhat.com>2023-10-18 08:01:09 +0200
commit8639a3e5f7d9622757abd77ee0f9f189ee7334a5 (patch)
tree2253f25e76c00c6ecb6cf422c9f6236ad6918e6d
parent12f694902d03c5ae41a4afe1dcd60bf91b6ac3a9 (diff)
dhcp (dhclient): honor ipv4.dhcp-client-id=none
If the client-id has been set to "none", the DHCP client-id option (option 61) mustn't be sent. Honor this when the dhclient plugin is used. If dhclient has been called with the -i option (Use a DUID with DHCPv4 clients), it will send a Client-ID even without setting one in dhclient.conf. In this case, this option needs to be explicitly overwritten with: send dhcp-client-identifier = ""; At least in RHEL 8, dhclient is launched with `-i` turned on by default.
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient-utils.c12
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient-utils.h1
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient.c4
-rw-r--r--src/core/dhcp/tests/test-dhcp-dhclient.c100
4 files changed, 109 insertions, 8 deletions
diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c
index ea8943fa1e..286f7aa19f 100644
--- a/src/core/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c
@@ -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");
diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.h b/src/core/dhcp/nm-dhcp-dhclient-utils.h
index 6187cce0fb..34b2617512 100644
--- a/src/core/dhcp/nm-dhcp-dhclient-utils.h
+++ b/src/core/dhcp/nm-dhcp-dhclient-utils.h
@@ -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,
diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c
index e6357871ef..2a3af10a56 100644
--- a/src/core/dhcp/nm-dhcp-dhclient.c
+++ b/src/core/dhcp/nm-dhcp-dhclient.c
@@ -233,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,
@@ -271,6 +272,7 @@ create_dhclient_config(NMDhcpDhclient *self,
new_content = nm_dhcp_dhclient_create_config(iface,
addr_family,
client_id,
+ send_client_id,
anycast_address,
hostname,
timeout,
@@ -515,6 +517,7 @@ ip4_start(NMDhcpClient *client, GError **error)
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,
@@ -557,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,
diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c
index e95f218e6e..0edcc296b4 100644
--- a/src/core/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/core/dhcp/tests/test-dhcp-dhclient.c
@@ -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;
-
- if (dhcp_client_id) {
+ 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 (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);