dhcp-client4: implement additional DHCP request options

Implement requesting additional DHCP options in the internal DHCPv4
client and encode the returned values as hex string to be used by
external components like dispatcher scripts.
This commit is contained in:
Sven Püschel 2025-10-29 16:02:20 +01:00
parent 2cad3544a0
commit 75c1ddce19
2 changed files with 43 additions and 2 deletions

View file

@ -18,6 +18,7 @@
#include "libnm-glib-aux/nm-dedup-multi.h"
#include "libnm-glib-aux/nm-io-utils.h"
#include "libnm-glib-aux/nm-str-buf.h"
#include "libnm-glib-aux/nm-shared-utils.h"
#include "libnm-std-aux/unaligned.h"
#include "NetworkManagerUtils.h"
@ -636,11 +637,14 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
const guint8 *l_data;
gsize l_data_len;
const char *v_str;
char *v_mut_str;
guint16 v_u16;
in_addr_t v_inaddr;
in_addr_t lease_address;
struct in_addr v_inaddr_s;
int r;
gsize i;
const NMDhcpClientConfig *client_config;
nm_assert(lease);
@ -650,6 +654,8 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE);
client_config = nm_dhcp_client_get_config(NM_DHCP_CLIENT(self));
if (!lease_parse_address(self, lease, l3cd, iface, options, &lease_address, error))
return NULL;
@ -703,8 +709,6 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
nm_str_buf_reset(&sbuf);
if (domains) {
gsize i;
for (i = 0; domains[i]; i++) {
gs_free char *s = NULL;
@ -865,6 +869,19 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
_add_option(options, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, v_str ?: "");
}
for (i = 0; i < client_config->request_additional_options->len; i++) {
guint8 option_id = nm_g_array_index(client_config->request_additional_options, guint16, i);
r = _client_lease_query(lease, option_id, &l_data, &l_data_len);
if (r == 0) {
v_mut_str = nm_utils_bin2hexstr_fuller(l_data, l_data_len, '\0', TRUE, TRUE, NULL);
nm_dhcp_option_take_option(options,
TRUE,
AF_INET,
option_id,
g_steal_pointer(&v_mut_str));
}
}
lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf);
lease_parse_address_list(lease,
@ -1430,6 +1447,12 @@ ip4_start(NMDhcpClient *client, GError **error)
NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED);
}
for (i = 0; i < client_config->request_additional_options->len; i++) {
n_dhcp4_client_probe_config_request_option(
config,
nm_g_array_index(client_config->request_additional_options, guint16, i));
}
if (client_config->mud_url) {
r = n_dhcp4_client_probe_config_append_option(config,
NM_DHCP_OPTION_DHCP4_MUD_URL,

View file

@ -7,6 +7,7 @@
#include "nm-setting-ip4-config.h"
#include "libnm-glib-aux/nm-shared-utils.h"
#include "nm-setting-private.h"
#include "nm-utils-private.h"
@ -195,6 +196,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG(setting);
NMSettingVerifyResult ret;
const char *method;
gsize i;
ret = NM_SETTING_CLASS(nm_setting_ip4_config_parent_class)->verify(setting, connection, error);
if (ret != NM_SETTING_VERIFY_SUCCESS)
@ -391,6 +393,22 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
&& !nm_utils_validate_dhcp4_vendor_class_id(priv->dhcp_vendor_class_identifier, error))
return FALSE;
for (i = 0; i < nm_g_array_len(priv->parent.dhcp_request_options); i++) {
guint32 value = nm_g_array_index(priv->parent.dhcp_request_options, guint32, i);
if (value > 255) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("DHCPv4 options value %d higher than the maximum possible value 255"),
value);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_DHCP_REQUEST_OPTIONS);
return FALSE;
}
}
/* Failures from here on are NORMALIZABLE_ERROR... */
if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)