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.
This commit is contained in:
Thomas Haller 2023-02-14 21:16:05 +01:00
parent 5a05ba398b
commit 07f1789725
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 29 additions and 5 deletions

View file

@ -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"

View file

@ -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;