summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-02-14 21:16:05 +0100
committerThomas Haller <thaller@redhat.com>2023-02-21 09:20:51 +0100
commit07f1789725726506cb3ba379ac53bd9bd720654b (patch)
tree3a2a47fae1017715c232a4b648fcc25f5c3d9f13
parent5a05ba398bff1b0a2da8f5462a2e85656d2ddc55 (diff)
downloadNetworkManager-07f1789725726506cb3ba379ac53bd9bd720654b.tar.gz
dhcp: add the DHCPv6 IAID to the lease information
We already get the IAID from the dhclient environment. This is actually rather useful, because dhclient plugin does not support setting the value (that is, what we request in "config.v6.iaid" is not actually used). Already previously, was the IAID for dhclient present in the lease information. Now also normalize/verify it. Expose the used IAID also with the internal (systemd) plugin. There we explicitly set the IAID and know it.
-rw-r--r--src/core/dhcp/nm-dhcp-client.c22
-rw-r--r--src/core/dhcp/nm-dhcp-systemd.c12
2 files changed, 29 insertions, 5 deletions
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c
index 370ae93832..1fc2d94461 100644
--- a/src/core/dhcp/nm-dhcp-client.c
+++ b/src/core/dhcp/nm-dhcp-client.c
@@ -241,7 +241,8 @@ nm_dhcp_client_create_l3cd(NMDhcpClient *self)
GHashTable *
nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys)
{
- NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
+ NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
+ const int IS_IPv4 = NM_IS_IPv4(priv->config.addr_family);
GHashTable *options;
GBytes *effective_client_id;
@@ -249,9 +250,8 @@ nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys)
effective_client_id = nm_dhcp_client_get_effective_client_id(self);
if (effective_client_id) {
- guint option = NM_IS_IPv4(priv->config.addr_family) ? NM_DHCP_OPTION_DHCP4_CLIENT_ID
- : NM_DHCP_OPTION_DHCP6_CLIENT_ID;
- gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id);
+ guint option = IS_IPv4 ? NM_DHCP_OPTION_DHCP4_CLIENT_ID : NM_DHCP_OPTION_DHCP6_CLIENT_ID;
+ gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id);
/* Note that for the nm-dhcp-helper based plugins (dhclient), the plugin
* may send the used client-id/DUID via the environment variables and
@@ -1588,6 +1588,20 @@ maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant
str_value = nm_dhcp_utils_duid_to_string(bytes);
}
+ if (!IS_IPv4 && nm_streq(key, "iaid")) {
+ gs_free char *str = g_steal_pointer(&str_value);
+ guint32 iaid;
+
+ /* Validate and normalize the iaid. */
+
+ if (!nm_dhcp_iaid_from_hexstr(str, &iaid)) {
+ /* Seems invalid. Ignore */
+ return;
+ }
+
+ str_value = nm_dhcp_iaid_to_hexstr(iaid, g_malloc(NM_DHCP_IAID_TO_HEXSTR_BUF_LEN));
+ }
+
g_hash_table_insert(hash, g_strdup(key), str_value);
/* dhclient has no special labels for private dhcp options: it uses "unknown_xyz"
diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c
index 3fd680fb30..6f9312da27 100644
--- a/src/core/dhcp/nm-dhcp-systemd.c
+++ b/src/core/dhcp/nm-dhcp-systemd.c
@@ -70,11 +70,13 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
static NML3ConfigData *
lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GError **error)
{
+ const NMDhcpClientConfig *config;
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_unref_hashtable GHashTable *options = NULL;
struct in6_addr tmp_addr;
const struct in6_addr *dns;
char addr_str[NM_INET_ADDRSTRLEN];
+ char iaid_buf[NM_DHCP_IAID_TO_HEXSTR_BUF_LEN];
char **domains;
char **ntp_fqdns;
const struct in6_addr *ntp_addrs;
@@ -84,11 +86,19 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro
nm_assert(lease);
+ config = nm_dhcp_client_get_config(NM_DHCP_CLIENT(self));
+
l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self));
options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE);
- if (!nm_dhcp_client_get_config(NM_DHCP_CLIENT(self))->v6.info_only) {
+ nm_dhcp_option_add_option(options,
+ TRUE,
+ AF_INET6,
+ NM_DHCP_OPTION_DHCP6_NM_IAID,
+ nm_dhcp_iaid_to_hexstr(config->v6.iaid, iaid_buf));
+
+ if (!config->v6.info_only) {
gboolean has_any_addresses = FALSE;
uint32_t lft_pref;
uint32_t lft_valid;