libnm: rework normalization of "wifi.mac-address-randomization"

The previous code is not entirely obvious, because as always,
verify() and normalize() must agree in what they are about to
do.

Make that clearer by adding _nm_setting_wireless_normalize_mac_address_randomization(),
which evaluates the desired settings. This is the used both by verify()
and normalize().
This commit is contained in:
Thomas Haller 2023-12-12 19:36:35 +01:00
parent c574f36ba4
commit 76a84e11df
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 95 additions and 57 deletions

View file

@ -1430,52 +1430,42 @@ again:
}
static gboolean
_normalize_wireless_mac_address_randomization(NMConnection *self)
_normalize_wireless_mac_address_randomization(NMSettingWireless *s_wifi)
{
NMSettingWireless *s_wifi = nm_connection_get_setting_wireless(self);
const char *desired_cloned_mac_address;
const char *cloned_mac_address;
NMSettingMacRandomization desired_mac_address_randomization;
NMSettingMacRandomization mac_address_randomization;
gboolean changed = FALSE;
if (!s_wifi)
return FALSE;
_nm_setting_wireless_normalize_mac_address_randomization(s_wifi,
&desired_cloned_mac_address,
&desired_mac_address_randomization);
mac_address_randomization = nm_setting_wireless_get_mac_address_randomization(s_wifi);
if (!NM_IN_SET(mac_address_randomization,
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
NM_SETTING_MAC_RANDOMIZATION_NEVER,
NM_SETTING_MAC_RANDOMIZATION_ALWAYS))
return FALSE;
cloned_mac_address = nm_setting_wireless_get_cloned_mac_address(s_wifi);
cloned_mac_address = nm_setting_wireless_get_cloned_mac_address(s_wifi);
if (cloned_mac_address) {
if (nm_streq(cloned_mac_address, "random")) {
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS)
return FALSE;
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS;
} else if (nm_streq(cloned_mac_address, "permanent")) {
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER)
return FALSE;
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
} else {
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
return FALSE;
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
}
g_object_set(s_wifi,
NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
mac_address_randomization,
NULL);
return TRUE;
}
if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
/* Note that "mac_address_randomization" is possibly the string owned by
* "s_wifi". We must be careful that modifying "s_wifi" might invalidate
* the string. */
if (!nm_streq0(cloned_mac_address, desired_cloned_mac_address)) {
g_object_set(s_wifi,
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS ? "random"
: "permanent",
desired_cloned_mac_address,
NULL);
return TRUE;
changed = TRUE;
}
return FALSE;
if (mac_address_randomization != desired_mac_address_randomization) {
g_object_set(s_wifi,
NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
(guint) desired_mac_address_randomization,
NULL);
changed = TRUE;
}
return changed;
}
static gboolean
@ -1497,6 +1487,9 @@ _normalize_wireless(NMConnection *self)
changed = TRUE;
}
if (_normalize_wireless_mac_address_randomization(s_wifi))
changed = TRUE;
return changed;
}
@ -2043,7 +2036,6 @@ _connection_normalize(NMConnection *connection,
was_modified |= _normalize_infiniband(connection);
was_modified |= _normalize_bond_mode(connection);
was_modified |= _normalize_bond_options(connection);
was_modified |= _normalize_wireless_mac_address_randomization(connection);
was_modified |= _normalize_wireless(connection);
was_modified |= _normalize_macsec(connection);
was_modified |= _normalize_team_config(connection);

View file

@ -1113,4 +1113,11 @@ _nm_sett_info_prop_from_dbus_fcn_cloned_mac_address(_NM_SETT_INFO_PROP_FROM_DBUS
/*****************************************************************************/
void _nm_setting_wireless_normalize_mac_address_randomization(
NMSettingWireless *s_wifi,
const char **out_cloned_mac_address,
NMSettingMacRandomization *out_mac_address_randomization);
/*****************************************************************************/
#endif /* NM_SETTING_PRIVATE_H */

View file

@ -829,6 +829,49 @@ nm_setting_wireless_get_ap_isolation(NMSettingWireless *setting)
/*****************************************************************************/
void
_nm_setting_wireless_normalize_mac_address_randomization(
NMSettingWireless *s_wifi,
const char **out_cloned_mac_address,
NMSettingMacRandomization *out_mac_address_randomization)
{
NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(s_wifi);
guint32 mac_address_randomization;
const char *cloned_mac_address;
mac_address_randomization = priv->mac_address_randomization;
cloned_mac_address = priv->cloned_mac_address;
if (cloned_mac_address) {
/* If cloned_mac_address is set, it takes precedence and determines
* mac_address_randomization. */
if (nm_streq(cloned_mac_address, "random"))
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS;
else if (nm_streq(cloned_mac_address, "permanent"))
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
else
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
} else if (!NM_IN_SET(mac_address_randomization,
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
NM_SETTING_MAC_RANDOMIZATION_NEVER,
NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) {
/* cloned_mac_address is NULL and mac_address_randomization is invalid. Normalize
* mac_address_randomization to the default. */
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
} else if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
/* mac_address_randomization is not (guint32)set to the default. cloned_mac_address gets
* overwritten. */
cloned_mac_address = mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS
? "random"
: "permanent";
}
*out_cloned_mac_address = cloned_mac_address;
*out_mac_address_randomization = mac_address_randomization;
}
/*****************************************************************************/
static gboolean
verify(NMSetting *setting, NMConnection *connection, GError **error)
{
@ -842,6 +885,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
guint i;
gsize length;
GError *local = NULL;
const char *desired_cloned_mac_address;
NMSettingMacRandomization desired_mac_address_randomization;
if (!priv->ssid) {
g_set_error_literal(error,
@ -1087,27 +1132,21 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
/* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */
if (priv->cloned_mac_address) {
if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS
&& nm_streq(priv->cloned_mac_address, "random"))
goto mac_addr_rand_ok;
if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER
&& nm_streq(priv->cloned_mac_address, "permanent"))
goto mac_addr_rand_ok;
if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
goto mac_addr_rand_ok;
} else if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
goto mac_addr_rand_ok;
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("conflicting value of mac-address-randomization and cloned-mac-address"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS);
return NM_SETTING_VERIFY_NORMALIZABLE;
mac_addr_rand_ok:
_nm_setting_wireless_normalize_mac_address_randomization(NM_SETTING_WIRELESS(setting),
&desired_cloned_mac_address,
&desired_mac_address_randomization);
if (desired_mac_address_randomization != priv->mac_address_randomization
|| !nm_streq0(desired_cloned_mac_address, priv->cloned_mac_address)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("conflicting value of mac-address-randomization and cloned-mac-address"));
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS);
return NM_SETTING_VERIFY_NORMALIZABLE;
}
if (priv->tx_power != 0 || priv->rate != 0) {
g_set_error(error,