From 7f1b1f50fa04af2e19779c8e18fbf4b82992891f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 17 Nov 2022 10:57:18 +0100 Subject: [PATCH] device: remember whether the DHCP client-id/duid is a fixed value Remember when the client-id is set to a explicit fixed value, so that we can take decision based on that (such as, whether the DHCP client can be restarted without the risk that the lease changes). This is not perfect because for client-id we accept also "stable", which may also translate to a fixed value depending on the value of another property. For now, only evaluate whether the properties contain explicit fixed values. --- src/core/devices/nm-device.c | 53 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 7783a82e68..5ad1192b37 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -240,6 +240,7 @@ typedef struct { NMDhcpConfig *config; gulong notify_sigid; NMDeviceIPState state; + bool client_id_fixed : 1; union { struct { } v4; @@ -802,7 +803,8 @@ static gint64 _get_carrier_wait_ms(NMDevice *self); static GBytes *_prop_get_ipv6_dhcp_duid(NMDevice *self, NMConnection *connection, GBytes *hwaddr, - gboolean *out_enforce); + gboolean *out_enforce, + gboolean *out_is_fixed); static const char *_activation_func_to_string(ActivationHandleFunc func); @@ -1094,7 +1096,8 @@ static GBytes * _prop_get_ipv6_dhcp_duid(NMDevice *self, NMConnection *connection, GBytes *hwaddr, - gboolean *out_enforce) + gboolean *out_enforce, + gboolean *out_is_fixed) { NMSettingIPConfig *s_ip6; const char *duid; @@ -1108,6 +1111,7 @@ _prop_get_ipv6_dhcp_duid(NMDevice *self, s_ip6 = nm_connection_get_setting_ip6_config(connection); duid = nm_setting_ip6_config_get_dhcp_duid(NM_SETTING_IP6_CONFIG(s_ip6)); + NM_SET_OUT(out_is_fixed, FALSE); if (!duid) { duid = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, @@ -1128,8 +1132,10 @@ _prop_get_ipv6_dhcp_duid(NMDevice *self, goto out_fail; } - if (duid_out) + if (duid_out) { + NM_SET_OUT(out_is_fixed, TRUE); goto out_good; + } if (NM_IN_STRSET(duid, "ll", "llt")) { if (!hwaddr) { @@ -1800,7 +1806,8 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, int addr_family, NMConnection *connection, gboolean log_silent, - gboolean *out_is_explicit) + gboolean *out_is_explicit, + gboolean *out_is_fixed) { const int IS_IPv4 = NM_IS_IPv4(addr_family); NMSettingIPConfig *s_ip; @@ -1810,6 +1817,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, const char *fail_reason; gboolean is_explicit = TRUE; + NM_SET_OUT(out_is_fixed, FALSE); s_ip = nm_connection_get_setting_ip_config(connection, addr_family); iaid_str = nm_setting_ip_config_get_dhcp_iaid(s_ip); if (!iaid_str) { @@ -1891,6 +1899,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice *self, iaid = unaligned_read_be32(digest); goto out_good; } else if ((iaid = _nm_utils_ascii_str_to_int64(iaid_str, 10, 0, G_MAXUINT32, -1)) != -1) { + NM_SET_OUT(out_is_fixed, TRUE); goto out_good; } else { iface = nm_device_get_ip_iface(self); @@ -2000,7 +2009,10 @@ _prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con) } static GBytes * -_prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes *hwaddr) +_prop_get_ipv4_dhcp_client_id(NMDevice *self, + NMConnection *connection, + GBytes *hwaddr, + gboolean *out_is_fixed) { NMSettingIPConfig *s_ip4; const char *client_id; @@ -2015,6 +2027,7 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * s_ip4 = nm_connection_get_setting_ip4_config(connection); client_id = nm_setting_ip4_config_get_dhcp_client_id(NM_SETTING_IP4_CONFIG(s_ip4)); + NM_SET_OUT(out_is_fixed, FALSE); if (!client_id) { client_id = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, @@ -2072,7 +2085,7 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * } if (nm_streq(client_id, "duid")) { - guint32 iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET, connection, FALSE, NULL); + guint32 iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET, connection, FALSE, NULL, NULL); result = nm_utils_dhcp_client_id_systemd_node_specific(iaid); goto out_good; @@ -2085,11 +2098,16 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * const guint8 *duid_arr; gsize duid_len; - iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET, connection, FALSE, &iaid_is_explicit); + iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET, connection, FALSE, &iaid_is_explicit, NULL); if (!iaid_is_explicit) - iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, FALSE, &iaid_is_explicit); + iaid = _prop_get_ipvx_dhcp_iaid(self, + AF_INET6, + connection, + FALSE, + &iaid_is_explicit, + NULL); - duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, NULL); + duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, NULL, NULL); nm_assert(duid); @@ -2130,6 +2148,7 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * } result = nm_dhcp_utils_client_id_string_to_bytes(client_id); + NM_SET_OUT(out_is_fixed, TRUE); goto out_good; out_fail: @@ -10429,8 +10448,9 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) const char *const *reject_servers; const char *hostname; gboolean hostname_is_fqdn; + gboolean client_id_fixed; - client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr); + client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr, &client_id_fixed); vendor_class_identifier = _prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip)); reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip, NULL); @@ -10471,14 +10491,22 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) priv->ipdhcp_data_4.client = nm_dhcp_manager_start_client(nm_dhcp_manager_get(), &config, &error); + priv->ipdhcp_data_4.client_id_fixed = client_id_fixed; } else { gs_unref_bytes GBytes *duid = NULL; gboolean iaid_explicit; + gboolean iaid_fixed; + gboolean duid_fixed; guint32 iaid; NMDhcpClientConfig config; - iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, FALSE, &iaid_explicit); - duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid); + iaid = _prop_get_ipvx_dhcp_iaid(self, + AF_INET6, + connection, + FALSE, + &iaid_explicit, + &iaid_fixed); + duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid, &duid_fixed); config = (NMDhcpClientConfig){ .addr_family = AF_INET6, @@ -10504,6 +10532,7 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) priv->ipdhcp_data_6.client = nm_dhcp_manager_start_client(nm_dhcp_manager_get(), &config, &error); + priv->ipdhcp_data_6.client_id_fixed = (duid_fixed && iaid_fixed); } if (!priv->ipdhcp_data_x[IS_IPv4].client) {