diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 498f77c119..789553aabd 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -240,7 +240,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; @@ -248,9 +249,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 @@ -1564,6 +1564,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 24bc2b1ef8..65d987b855 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_UTILS_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;