diff options
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 |
commit | 8639a3e5f7d9622757abd77ee0f9f189ee7334a5 (patch) | |
tree | 2253f25e76c00c6ecb6cf422c9f6236ad6918e6d | |
parent | 12f694902d03c5ae41a4afe1dcd60bf91b6ac3a9 (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.c | 12 | ||||
-rw-r--r-- | src/core/dhcp/nm-dhcp-dhclient-utils.h | 1 | ||||
-rw-r--r-- | src/core/dhcp/nm-dhcp-dhclient.c | 4 | ||||
-rw-r--r-- | src/core/dhcp/tests/test-dhcp-dhclient.c | 100 |
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); |