diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 2430acec59..fd8e7dbb5c 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -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); diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index aaaaaf8c4e..5137a44808 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -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 */ diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c index a02bfa7eb4..0bc72116b9 100644 --- a/src/libnm-core-impl/nm-setting-wireless.c +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -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,