diff options
| author | Michael Biebl <biebl@debian.org> | 2024-01-25 09:46:18 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2024-01-25 09:46:18 +0100 |
| commit | 70e18d99b8e3e77bb37e218d7ac582130156f8ef (patch) | |
| tree | d40c587e6d3f0e094ff558e415f1bb9803643214 /src/core/dhcp | |
| parent | d4d8b2b91f7ba000d97a8b2aab48c85000c11314 (diff) | |
New upstream version 1.45.90 upstream/1.45.90
Diffstat (limited to 'src/core/dhcp')
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.c | 2 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.h | 3 | ||||
| -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 | 125 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-dhcpcd.c | 2 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-helper.c | 4 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 40 | ||||
| -rw-r--r-- | src/core/dhcp/tests/test-dhcp-dhclient.c | 100 |
9 files changed, 187 insertions, 102 deletions
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 6978bd3c..4be03f4b 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -527,7 +527,7 @@ _acd_reglist_data_remove(NMDhcpClient *self, guint idx, gboolean do_log) nm_clear_l3cd(®list_data->l3cd); - nm_l3cfg_commit_on_idle_schedule(priv->config.l3cfg, NM_L3_CFG_COMMIT_TYPE_UPDATE); + nm_l3cfg_commit_on_idle_schedule(priv->config.l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO); g_array_remove_index(priv->v4.acd.reglist, idx); diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index 903ea6ac..4dd2c4fd 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -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 diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c index ea8943fa..286f7aa1 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 6187cce0..34b26175 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 4aab4b1e..2a3af10a 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -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); - - _LOGD("creating composite dhclient config %s", new); + 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); - 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)) { + 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); + } + } + + 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_clear_error(&error); + g_error_free(error); + g_free(new_path); + return NULL; } - return new; + 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, diff --git a/src/core/dhcp/nm-dhcp-dhcpcd.c b/src/core/dhcp/nm-dhcp-dhcpcd.c index 8d2f928b..7c95994a 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcd.c +++ b/src/core/dhcp/nm-dhcp-dhcpcd.c @@ -174,7 +174,7 @@ stop(NMDhcpClient *client, gboolean release) */ if (kill(pid, sig) == -1) { errsv = errno; - _LOGE("failed to kill dhcpcd %d:%s", errsv, strerror(errsv)); + _LOGE("failed to kill dhcpcd %d:%s", errsv, nm_strerror_native(errsv)); } /* When this function exits NM expects the PID to be -1. diff --git a/src/core/dhcp/nm-dhcp-helper.c b/src/core/dhcp/nm-dhcp-helper.c index ee95abb7..9e4cedf2 100644 --- a/src/core/dhcp/nm-dhcp-helper.c +++ b/src/core/dhcp/nm-dhcp-helper.c @@ -159,7 +159,7 @@ do_connect: error->message, try_count, (long long) (time_end - remaining_time - time_start) / 1000); - interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31))), 5000, 100000); + interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31u))), 5000, 100000); g_usleep(NM_MIN(interval, remaining_time)); g_clear_error(&error); goto do_connect; @@ -222,7 +222,7 @@ do_notify: gint64 interval; _LOGi("failure to call notify: %s (retry %u)", error->message, try_count); - interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31))), 5000, 25000); + interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31u))), 5000, 25000); g_usleep(NM_MIN(interval, remaining_time)); g_clear_error(&error); goto do_notify; diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index f36dfb4d..fc468d4c 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -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; diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index e95f218e..0edcc296 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); |