mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 23:40:10 +01:00
libnm: merge branch 'th/libnm-setting-compare'
https://github.com/NetworkManager/NetworkManager/pull/277
This commit is contained in:
commit
4d2b324b52
18 changed files with 703 additions and 457 deletions
|
|
@ -707,10 +707,18 @@ _nm_sett_info_property_info_get_sorted (const NMSettInfoSetting *sett_info,
|
|||
: &sett_info->property_infos[idx];
|
||||
}
|
||||
|
||||
const NMSettInfoSetting *_nm_sett_info_setting_get (NMSettingClass *setting_class);
|
||||
const NMSettInfoProperty *_nm_sett_info_setting_get_property_info (const NMSettInfoSetting *sett_info,
|
||||
const char *property_name);
|
||||
|
||||
const NMSettInfoProperty *_nm_sett_info_property_get (NMSettingClass *setting_class,
|
||||
const char *property_name);
|
||||
const NMSettInfoSetting *_nm_setting_class_get_sett_info (NMSettingClass *setting_class);
|
||||
|
||||
static inline const NMSettInfoProperty *
|
||||
_nm_setting_class_get_property_info (NMSettingClass *setting_class,
|
||||
const char *property_name)
|
||||
{
|
||||
return _nm_sett_info_setting_get_property_info (_nm_setting_class_get_sett_info (setting_class),
|
||||
property_name);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -2815,7 +2815,7 @@ _read_setting (KeyfileReaderInfo *info)
|
|||
|
||||
info->setting = setting;
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
gs_free char **keys = NULL;
|
||||
|
|
@ -3232,7 +3232,7 @@ nm_keyfile_write (NMConnection *connection,
|
|||
const NMSettInfoSetting *sett_info;
|
||||
NMSetting *setting = settings[i];
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
guint k, n_keys;
|
||||
|
|
|
|||
|
|
@ -811,15 +811,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
options_hash_match (NMSettingBond *s_bond,
|
||||
GHashTable *options1,
|
||||
GHashTable *options2,
|
||||
options_equal_asym (NMSettingBond *s_bond,
|
||||
NMSettingBond *s_bond2,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
GHashTable *options2 = NM_SETTING_BOND_GET_PRIVATE (s_bond2)->options;
|
||||
GHashTableIter iter;
|
||||
const char *key, *value, *value2;
|
||||
|
||||
g_hash_table_iter_init (&iter, options1);
|
||||
g_hash_table_iter_init (&iter, NM_SETTING_BOND_GET_PRIVATE (s_bond)->options);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
|
||||
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) {
|
||||
|
|
@ -841,15 +841,10 @@ options_hash_match (NMSettingBond *s_bond,
|
|||
value2 = g_hash_table_lookup (options2, "num_grat_arp");
|
||||
}
|
||||
|
||||
if (value2) {
|
||||
if (nm_streq (value, value2))
|
||||
continue;
|
||||
} else {
|
||||
if (nm_streq (value, nm_setting_bond_get_option_default (s_bond, key)))
|
||||
continue;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
if (!value2)
|
||||
value2 = nm_setting_bond_get_option_default (s_bond2, key);
|
||||
if (!nm_streq (value, value2))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -857,31 +852,32 @@ options_hash_match (NMSettingBond *s_bond,
|
|||
|
||||
static gboolean
|
||||
options_equal (NMSettingBond *s_bond,
|
||||
GHashTable *options1,
|
||||
GHashTable *options2,
|
||||
NMSettingBond *s_bond2,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
return options_hash_match (s_bond, options1, options2, flags)
|
||||
&& options_hash_match (s_bond, options2, options1, flags);
|
||||
return options_equal_asym (s_bond, s_bond2, flags)
|
||||
&& options_equal_asym (s_bond2, s_bond, flags);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingClass *setting_class;
|
||||
|
||||
if (nm_streq0 (prop_spec->name, NM_SETTING_BOND_OPTIONS)) {
|
||||
return options_equal (NM_SETTING_BOND (setting),
|
||||
NM_SETTING_BOND_GET_PRIVATE (setting)->options,
|
||||
NM_SETTING_BOND_GET_PRIVATE (other)->options,
|
||||
flags);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_BOND_OPTIONS)) {
|
||||
return ( !other
|
||||
|| options_equal (NM_SETTING_BOND (setting),
|
||||
NM_SETTING_BOND (other),
|
||||
flags));
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_bond_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_bond_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1281,23 +1281,26 @@ nm_setting_connection_no_interface_name (NMSetting *setting,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
/* Handle ignore ID */
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
|
||||
&& g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_ID) == 0)
|
||||
return TRUE;
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_ID)
|
||||
&& nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_ID))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
/* Handle ignore timestamp */
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)
|
||||
&& g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_TIMESTAMP) == 0)
|
||||
return TRUE;
|
||||
if ( NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)
|
||||
&& nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_TIMESTAMP))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -2612,44 +2612,52 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingIPConfigPrivate *a_priv, *b_priv;
|
||||
NMSettingClass *setting_class;
|
||||
NMSettingIPConfigPrivate *a_priv;
|
||||
NMSettingIPConfigPrivate *b_priv;
|
||||
guint i;
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ADDRESSES)) {
|
||||
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ADDRESSES)) {
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||
|
||||
if (a_priv->addresses->len != b_priv->addresses->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->addresses->len; i++) {
|
||||
if (!_nm_ip_address_equal (a_priv->addresses->pdata[i], b_priv->addresses->pdata[i], TRUE))
|
||||
if (a_priv->addresses->len != b_priv->addresses->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->addresses->len; i++) {
|
||||
if (!_nm_ip_address_equal (a_priv->addresses->pdata[i], b_priv->addresses->pdata[i], TRUE))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ROUTES)) {
|
||||
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ROUTES)) {
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||
|
||||
if (a_priv->routes->len != b_priv->routes->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->routes->len; i++) {
|
||||
if (!nm_ip_route_equal_full (a_priv->routes->pdata[i], b_priv->routes->pdata[i], NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS))
|
||||
if (a_priv->routes->len != b_priv->routes->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->routes->len; i++) {
|
||||
if (!nm_ip_route_equal_full (a_priv->routes->pdata[i], b_priv->routes->pdata[i], NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_ip_config_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_ip_config_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -201,6 +201,11 @@ gboolean _nm_setting_use_legacy_property (NMSetting *setting,
|
|||
|
||||
GPtrArray *_nm_setting_need_secrets (NMSetting *setting);
|
||||
|
||||
gboolean _nm_setting_should_compare_secret_property (NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const char *secret_name,
|
||||
NMSettingCompareFlags flags);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* NM_SETTING_PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -1188,29 +1188,37 @@ get_property (GObject *object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingSriov *a = NM_SETTING_SRIOV (setting);
|
||||
NMSettingSriov *b = NM_SETTING_SRIOV (other);
|
||||
NMSettingClass *setting_class;
|
||||
NMSettingSriov *a;
|
||||
NMSettingSriov *b;
|
||||
guint i;
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_SRIOV_VFS)) {
|
||||
if (a->vfs->len != b->vfs->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a->vfs->len; i++) {
|
||||
if (!nm_sriov_vf_equal (a->vfs->pdata[i], b->vfs->pdata[i]))
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_SRIOV_VFS)) {
|
||||
if (other) {
|
||||
a = NM_SETTING_SRIOV (setting);
|
||||
b = NM_SETTING_SRIOV (other);
|
||||
|
||||
if (a->vfs->len != b->vfs->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a->vfs->len; i++) {
|
||||
if (!nm_sriov_vf_equal (a->vfs->pdata[i], b->vfs->pdata[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_sriov_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_sriov_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1233,39 +1233,46 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingTCConfig *a_tc_config = NM_SETTING_TC_CONFIG (setting);
|
||||
NMSettingTCConfig *b_tc_config = NM_SETTING_TC_CONFIG (other);
|
||||
NMSettingClass *setting_class;
|
||||
guint i;
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_TC_CONFIG_QDISCS)) {
|
||||
if (a_tc_config->qdiscs->len != b_tc_config->qdiscs->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_tc_config->qdiscs->len; i++) {
|
||||
if (!nm_tc_qdisc_equal (a_tc_config->qdiscs->pdata[i], b_tc_config->qdiscs->pdata[i]))
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_QDISCS)) {
|
||||
if (other) {
|
||||
if (a_tc_config->qdiscs->len != b_tc_config->qdiscs->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_tc_config->qdiscs->len; i++) {
|
||||
if (!nm_tc_qdisc_equal (a_tc_config->qdiscs->pdata[i], b_tc_config->qdiscs->pdata[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_TC_CONFIG_TFILTERS)) {
|
||||
if (a_tc_config->tfilters->len != b_tc_config->tfilters->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_tc_config->tfilters->len; i++) {
|
||||
if (!nm_tc_tfilter_equal (a_tc_config->tfilters->pdata[i], b_tc_config->tfilters->pdata[i]))
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_TFILTERS)) {
|
||||
if (other) {
|
||||
if (a_tc_config->tfilters->len != b_tc_config->tfilters->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_tc_config->tfilters->len; i++) {
|
||||
if (!nm_tc_tfilter_equal (a_tc_config->tfilters->pdata[i], b_tc_config->tfilters->pdata[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_tc_config_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_tc_config_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -401,48 +401,68 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingClass *setting_class;
|
||||
NMSettingTeamPortPrivate *a_priv, *b_priv;
|
||||
NMSettingTeamPortPrivate *a_priv;
|
||||
NMSettingTeamPortPrivate *b_priv;
|
||||
guint i, j;
|
||||
|
||||
/* If we are trying to match a connection in order to assume it (and thus
|
||||
* @flags contains INFERRABLE), use the "relaxed" matching for team
|
||||
* configuration. Otherwise, for all other purposes (including connection
|
||||
* comparison before an update), resort to the default string comparison.
|
||||
*/
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
|
||||
&& nm_streq0 (prop_spec->name, NM_SETTING_TEAM_PORT_CONFIG)) {
|
||||
return _nm_utils_team_config_equal (NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->config,
|
||||
NM_SETTING_TEAM_PORT_GET_PRIVATE (other)->config,
|
||||
TRUE);
|
||||
}
|
||||
if (nm_streq0 (prop_spec->name, NM_SETTING_TEAM_PORT_LINK_WATCHERS)) {
|
||||
a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (other);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_PORT_LINK_WATCHERS)) {
|
||||
|
||||
if (a_priv->link_watchers->len != b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->link_watchers->len; i++) {
|
||||
for (j = 0; j < b_priv->link_watchers->len; j++) {
|
||||
if (nm_team_link_watcher_equal (a_priv->link_watchers->pdata[i],
|
||||
b_priv->link_watchers->pdata[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == b_priv->link_watchers->len)
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (other);
|
||||
|
||||
if (a_priv->link_watchers->len != b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->link_watchers->len; i++) {
|
||||
for (j = 0; j < b_priv->link_watchers->len; j++) {
|
||||
if (nm_team_link_watcher_equal (a_priv->link_watchers->pdata[i],
|
||||
b_priv->link_watchers->pdata[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_team_port_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_PORT_CONFIG)) {
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (other);
|
||||
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) {
|
||||
/* If we are trying to match a connection in order to assume it (and thus
|
||||
* @flags contains INFERRABLE), use the "relaxed" matching for team
|
||||
* configuration. Otherwise, for all other purposes (including connection
|
||||
* comparison before an update), resort to the default string comparison. */
|
||||
return _nm_utils_team_config_equal (a_priv->config,
|
||||
b_priv->config,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
return nm_streq0 (a_priv->config, b_priv->config);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return NM_SETTING_CLASS (nm_setting_team_port_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1297,38 +1297,33 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingTeamPrivate *a_priv, *b_priv;
|
||||
NMSettingClass *setting_class;
|
||||
guint i, j;
|
||||
|
||||
/* If we are trying to match a connection in order to assume it (and thus
|
||||
* @flags contains INFERRABLE), use the "relaxed" matching for team
|
||||
* configuration. Otherwise, for all other purposes (including connection
|
||||
* comparison before an update), resort to the default string comparison.
|
||||
*/
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
|
||||
&& nm_streq0 (prop_spec->name, NM_SETTING_TEAM_CONFIG)) {
|
||||
return _nm_utils_team_config_equal (NM_SETTING_TEAM_GET_PRIVATE (setting)->config,
|
||||
NM_SETTING_TEAM_GET_PRIVATE (other)->config,
|
||||
FALSE);
|
||||
}
|
||||
if (nm_streq0 (prop_spec->name, NM_SETTING_TEAM_LINK_WATCHERS)) {
|
||||
a_priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_GET_PRIVATE (other);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_LINK_WATCHERS)) {
|
||||
|
||||
if (a_priv->link_watchers->len != b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->link_watchers->len; i++) {
|
||||
for (j = 0; j < b_priv->link_watchers->len; j++) {
|
||||
if (nm_team_link_watcher_equal (a_priv->link_watchers->pdata[i],
|
||||
b_priv->link_watchers->pdata[j])) {
|
||||
break;
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_GET_PRIVATE (other);
|
||||
|
||||
if (a_priv->link_watchers->len != b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < a_priv->link_watchers->len; i++) {
|
||||
for (j = 0; j < b_priv->link_watchers->len; j++) {
|
||||
if (nm_team_link_watcher_equal (a_priv->link_watchers->pdata[i],
|
||||
b_priv->link_watchers->pdata[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == b_priv->link_watchers->len)
|
||||
return FALSE;
|
||||
|
|
@ -1337,8 +1332,32 @@ compare_property (NMSetting *setting,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_team_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_CONFIG)) {
|
||||
if (other) {
|
||||
a_priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
|
||||
b_priv = NM_SETTING_TEAM_GET_PRIVATE (other);
|
||||
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) {
|
||||
/* If we are trying to match a connection in order to assume it (and thus
|
||||
* @flags contains INFERRABLE), use the "relaxed" matching for team
|
||||
* configuration. Otherwise, for all other purposes (including connection
|
||||
* comparison before an update), resort to the default string comparison. */
|
||||
return _nm_utils_team_config_equal (a_priv->config,
|
||||
b_priv->config,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
return nm_streq0 (a_priv->config, b_priv->config);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return NM_SETTING_CLASS (nm_setting_team_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -395,33 +395,34 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingUserPrivate *priv, *pri2;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_USER (setting), FALSE);
|
||||
g_return_val_if_fail (NM_IS_SETTING_USER (other), FALSE);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_USER_DATA)) {
|
||||
|
||||
if (!nm_streq0 (prop_spec->name, NM_SETTING_USER_DATA))
|
||||
goto call_parent;
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
priv = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (setting));
|
||||
pri2 = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (other));
|
||||
if (!other)
|
||||
return TRUE;
|
||||
|
||||
if (!nm_utils_hash_table_equal (priv->data, pri2->data, TRUE, g_str_equal))
|
||||
return FALSE;
|
||||
priv = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (setting));
|
||||
pri2 = NM_SETTING_USER_GET_PRIVATE (NM_SETTING_USER (other));
|
||||
return nm_utils_hash_table_equal (priv->data, pri2->data, TRUE, g_str_equal)
|
||||
&& nm_utils_hash_table_equal (priv->data_invalid, pri2->data_invalid, TRUE, g_str_equal);
|
||||
}
|
||||
|
||||
if (!nm_utils_hash_table_equal (priv->data_invalid, pri2->data_invalid, TRUE, g_str_equal))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
call_parent:
|
||||
return NM_SETTING_CLASS (nm_setting_user_parent_class)->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_user_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -765,77 +765,63 @@ need_secrets (NMSetting *setting)
|
|||
return g_ptr_array_sized_new (1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_compare_secrets (NMSettingVpn *a,
|
||||
NMSettingVpn *b,
|
||||
NMSettingCompareFlags flags)
|
||||
static NMTernary
|
||||
compare_property_secrets (NMSettingVpn *a,
|
||||
NMSettingVpn *b,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
GHashTable *a_secrets;
|
||||
GHashTableIter iter;
|
||||
const char *key, *val;
|
||||
int run;
|
||||
|
||||
a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets;
|
||||
g_hash_table_iter_init (&iter, a_secrets);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
|
||||
NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_FUZZY))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL);
|
||||
nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL);
|
||||
if (!b)
|
||||
return TRUE;
|
||||
|
||||
for (run = 0; run < 2; run++) {
|
||||
NMSettingVpn *current_a = (run == 0) ? a : b;
|
||||
NMSettingVpn *current_b = (run == 0) ? b : a;
|
||||
|
||||
g_hash_table_iter_init (&iter, NM_SETTING_VPN_GET_PRIVATE (current_a)->secrets);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
|
||||
|
||||
if (nm_streq0 (val, nm_setting_vpn_get_secret (current_b, key)))
|
||||
continue;
|
||||
if (!_nm_setting_should_compare_secret_property (NM_SETTING (current_a),
|
||||
NM_SETTING (current_b),
|
||||
key,
|
||||
flags))
|
||||
continue;
|
||||
|
||||
/* If the secret flags aren't the same, the settings aren't the same */
|
||||
if (a_secret_flags != b_secret_flags)
|
||||
return FALSE;
|
||||
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
continue;
|
||||
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
|
||||
continue;
|
||||
|
||||
/* Now compare the values themselves */
|
||||
if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_one_secret (NMSettingVpn *a,
|
||||
NMSettingVpn *b,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
if (!_compare_secrets (a, b, flags))
|
||||
return FALSE;
|
||||
if (!_compare_secrets (b, a, flags))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
gboolean same;
|
||||
|
||||
/* We only need to treat the 'secrets' property specially */
|
||||
if (g_strcmp0 (prop_spec->name, NM_SETTING_VPN_SECRETS) != 0)
|
||||
return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (setting, other, prop_spec, flags);
|
||||
|
||||
/* Compare A to B to ensure everything in A is found in B */
|
||||
same = compare_one_secret (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags);
|
||||
if (same) {
|
||||
/* And then B to A to ensure everything in B is also found in A */
|
||||
same = compare_one_secret (NM_SETTING_VPN (other), NM_SETTING_VPN (setting), flags);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_VPN_SECRETS)) {
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
return compare_property_secrets (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags);
|
||||
}
|
||||
|
||||
return same;
|
||||
return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -775,21 +775,25 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingClass *setting_class;
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) {
|
||||
return nm_streq0 (NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address,
|
||||
NM_SETTING_WIRED_GET_PRIVATE (other)->cloned_mac_address);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) {
|
||||
return !other
|
||||
|| nm_streq0 (NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address,
|
||||
NM_SETTING_WIRED_GET_PRIVATE (other)->cloned_mac_address);
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_wired_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_wired_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
|
|
|
|||
|
|
@ -929,21 +929,24 @@ mac_addr_rand_ok:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingClass *setting_class;
|
||||
|
||||
if (nm_streq (prop_spec->name, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)) {
|
||||
return nm_streq0 (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address,
|
||||
NM_SETTING_WIRELESS_GET_PRIVATE (other)->cloned_mac_address);
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)) {
|
||||
return !other
|
||||
|| nm_streq0 (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address,
|
||||
NM_SETTING_WIRELESS_GET_PRIVATE (other)->cloned_mac_address);
|
||||
}
|
||||
|
||||
setting_class = NM_SETTING_CLASS (nm_setting_wireless_parent_class);
|
||||
return setting_class->compare_property (setting, other, prop_spec, flags);
|
||||
return NM_SETTING_CLASS (nm_setting_wireless_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1452,6 +1455,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass)
|
|||
g_param_spec_string (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
_properties_override_add_override (properties_override,
|
||||
|
|
|
|||
|
|
@ -508,25 +508,15 @@ _nm_setting_class_commit_full (NMSettingClass *setting_class,
|
|||
setting_class);
|
||||
}
|
||||
|
||||
const NMSettInfoSetting *
|
||||
_nm_sett_info_setting_get (NMSettingClass *setting_class)
|
||||
{
|
||||
if ( NM_IS_SETTING_CLASS (setting_class)
|
||||
&& setting_class->setting_info) {
|
||||
nm_assert (setting_class->setting_info->meta_type < G_N_ELEMENTS (_sett_info_settings));
|
||||
return &_sett_info_settings[setting_class->setting_info->meta_type];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NMSettInfoProperty *
|
||||
_nm_sett_info_property_get (NMSettingClass *setting_class,
|
||||
const char *property_name)
|
||||
_nm_sett_info_setting_get_property_info (const NMSettInfoSetting *sett_info,
|
||||
const char *property_name)
|
||||
{
|
||||
const NMSettInfoSetting *sett_info = _nm_sett_info_setting_get (setting_class);
|
||||
const NMSettInfoProperty *property;
|
||||
gssize idx;
|
||||
|
||||
nm_assert (property_name);
|
||||
|
||||
if (!sett_info)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -549,6 +539,17 @@ _nm_sett_info_property_get (NMSettingClass *setting_class,
|
|||
return property;
|
||||
}
|
||||
|
||||
const NMSettInfoSetting *
|
||||
_nm_setting_class_get_sett_info (NMSettingClass *setting_class)
|
||||
{
|
||||
if ( NM_IS_SETTING_CLASS (setting_class)
|
||||
&& setting_class->setting_info) {
|
||||
nm_assert (setting_class->setting_info->meta_type < G_N_ELEMENTS (_sett_info_settings));
|
||||
return &_sett_info_settings[setting_class->setting_info->meta_type];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
|
|
@ -731,7 +732,7 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS
|
|||
g_hash_table_lookup (priv->gendata->hash, gendata_keys[i]));
|
||||
}
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
const NMSettInfoProperty *property = &sett_info->property_infos[i];
|
||||
GParamSpec *prop_spec = property->param_spec;
|
||||
|
|
@ -856,7 +857,7 @@ _nm_setting_new_from_dbus (GType setting_type,
|
|||
}
|
||||
}
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
GHashTable *hash;
|
||||
|
|
@ -1002,7 +1003,7 @@ nm_setting_get_dbus_property_type (NMSetting *setting,
|
|||
g_return_val_if_fail (NM_IS_SETTING (setting), NULL);
|
||||
g_return_val_if_fail (property_name != NULL, NULL);
|
||||
|
||||
property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), property_name);
|
||||
property = _nm_setting_class_get_property_info (NM_SETTING_GET_CLASS (setting), property_name);
|
||||
g_return_val_if_fail (property != NULL, NULL);
|
||||
|
||||
if (property->dbus_type)
|
||||
|
|
@ -1015,13 +1016,13 @@ gboolean
|
|||
_nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value)
|
||||
{
|
||||
const NMSettInfoSetting *sett_info;
|
||||
GParamSpec *prop_spec;
|
||||
const NMSettInfoProperty *property_info;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (property_name, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
GVariant *variant;
|
||||
|
|
@ -1039,13 +1040,14 @@ _nm_setting_get_property (NMSetting *setting, const char *property_name, GValue
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name);
|
||||
if (!prop_spec) {
|
||||
property_info = _nm_sett_info_setting_get_property_info (sett_info, property_name);
|
||||
if ( !property_info
|
||||
|| !property_info->param_spec) {
|
||||
g_value_unset (value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_value_init (value, prop_spec->value_type);
|
||||
g_value_init (value, property_info->param_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (setting), property_name, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1085,7 +1087,7 @@ nm_setting_duplicate (NMSetting *setting)
|
|||
|
||||
dup = g_object_new (G_OBJECT_TYPE (setting), NULL);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
GenData *gendata = _gendata_hash (setting, FALSE);
|
||||
|
|
@ -1241,58 +1243,148 @@ _nm_setting_verify_secret_string (const char *str,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
gboolean
|
||||
_nm_setting_should_compare_secret_property (NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const char *secret_name,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
const NMSettInfoProperty *property;
|
||||
GVariant *value1, *value2;
|
||||
int cmp;
|
||||
NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
/* Handle compare flags */
|
||||
if (prop_spec->flags & NM_SETTING_PARAM_SECRET) {
|
||||
NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (!other || G_OBJECT_TYPE (setting) == G_OBJECT_TYPE (other));
|
||||
|
||||
g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE);
|
||||
/* secret_name must be a valid secret for @setting. */
|
||||
nm_assert (nm_setting_get_secret_flags (setting, secret_name, NULL, NULL));
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (!nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (!NM_FLAGS_ANY (flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS
|
||||
| NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS))
|
||||
return TRUE;
|
||||
|
||||
/* If the secret flags aren't the same the settings aren't the same */
|
||||
if (a_secret_flags != b_secret_flags)
|
||||
return FALSE;
|
||||
|
||||
/* Check for various secret flags that might cause us to ignore comparing
|
||||
* this property.
|
||||
*/
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
return TRUE;
|
||||
|
||||
if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
|
||||
return TRUE;
|
||||
nm_setting_get_secret_flags (setting, secret_name, &a_secret_flags, NULL);
|
||||
if (other) {
|
||||
if (!nm_setting_get_secret_flags (other, secret_name, &b_secret_flags, NULL)) {
|
||||
/* secret-name may not be a valid secret for @other. That is fine, we ignore that
|
||||
* and treat @b_secret_flags as NM_SETTING_SECRET_FLAG_NONE.
|
||||
*
|
||||
* This can happen with VPN secrets, where the caller knows that @secret_name
|
||||
* is a secret for setting, but it may not be a secret for @other. Accept that.
|
||||
*
|
||||
* Mark @other as missing. */
|
||||
other = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), prop_spec->name);
|
||||
g_return_val_if_fail (property != NULL, FALSE);
|
||||
/* when @setting has the secret-flags that should be ignored,
|
||||
* we skip the comparisong if:
|
||||
*
|
||||
* - @other is not present,
|
||||
* - @other does not have a secret named @secret_name
|
||||
* - @other also has the secret flat to be ignored.
|
||||
*
|
||||
* This makes the check symmetric (aside the fact that @setting must
|
||||
* have the secret while @other may not -- which is asymetric). */
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& NM_FLAGS_HAS (a_secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)
|
||||
&& ( !other
|
||||
|| NM_FLAGS_HAS (b_secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)))
|
||||
return FALSE;
|
||||
|
||||
value1 = get_property_for_dbus (setting, property, TRUE);
|
||||
value2 = get_property_for_dbus (other, property, TRUE);
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& NM_FLAGS_HAS (a_secret_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
&& ( !other
|
||||
|| NM_FLAGS_HAS (b_secret_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)))
|
||||
return FALSE;
|
||||
|
||||
cmp = nm_property_compare (value1, value2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (value1)
|
||||
g_variant_unref (value1);
|
||||
if (value2)
|
||||
g_variant_unref (value2);
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx];
|
||||
const GParamSpec *param_spec = property_info->param_spec;
|
||||
|
||||
return cmp == 0;
|
||||
if (!param_spec)
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_FUZZY)
|
||||
&& NM_FLAGS_ANY (param_spec->flags, NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
|
||||
&& !NM_FLAGS_HAS (param_spec->flags, NM_SETTING_PARAM_INFERRABLE))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)
|
||||
&& NM_FLAGS_HAS (param_spec->flags, NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
&& NM_FLAGS_HAS (param_spec->flags, NM_SETTING_PARAM_SECRET))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if (nm_streq (param_spec->name, NM_SETTING_NAME))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if ( NM_FLAGS_HAS (param_spec->flags, NM_SETTING_PARAM_SECRET)
|
||||
&& !_nm_setting_should_compare_secret_property (setting,
|
||||
other,
|
||||
param_spec->name,
|
||||
flags))
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
if (other) {
|
||||
gs_unref_variant GVariant *value1 = NULL;
|
||||
gs_unref_variant GVariant *value2 = NULL;
|
||||
|
||||
value1 = get_property_for_dbus (setting, property_info, TRUE);
|
||||
value2 = get_property_for_dbus (other, property_info, TRUE);
|
||||
|
||||
if (nm_property_compare (value1, value2) != 0)
|
||||
return NM_TERNARY_FALSE;
|
||||
}
|
||||
|
||||
return NM_TERNARY_TRUE;
|
||||
}
|
||||
|
||||
static NMTernary
|
||||
_compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMTernary compare_result;
|
||||
|
||||
nm_assert (sett_info);
|
||||
nm_assert (NM_IS_SETTING_CLASS (sett_info->setting_class));
|
||||
nm_assert (property_idx < sett_info->property_infos_len);
|
||||
nm_assert (NM_SETTING_GET_CLASS (setting) == sett_info->setting_class);
|
||||
nm_assert (!other || NM_SETTING_GET_CLASS (other) == sett_info->setting_class);
|
||||
|
||||
compare_result = NM_SETTING_GET_CLASS (setting)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
|
||||
nm_assert (NM_IN_SET (compare_result, NM_TERNARY_DEFAULT,
|
||||
NM_TERNARY_FALSE,
|
||||
NM_TERNARY_TRUE));
|
||||
|
||||
/* check that the inferable flag and the GObject property flag corresponds. */
|
||||
nm_assert ( !NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
|
||||
|| !sett_info->property_infos[property_idx].param_spec
|
||||
|| NM_FLAGS_HAS (sett_info->property_infos[property_idx].param_spec->flags, NM_SETTING_PARAM_INFERRABLE)
|
||||
|| compare_result == NM_TERNARY_DEFAULT);
|
||||
|
||||
return compare_result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1322,7 +1414,7 @@ nm_setting_compare (NMSetting *a,
|
|||
if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b))
|
||||
return FALSE;
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (a));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (a));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
GenData *a_gendata = _gendata_hash (a, FALSE);
|
||||
|
|
@ -1334,93 +1426,14 @@ nm_setting_compare (NMSetting *a,
|
|||
g_variant_equal);
|
||||
}
|
||||
|
||||
/* And now all properties */
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
|
||||
|
||||
if (!prop_spec)
|
||||
continue;
|
||||
|
||||
/* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_FUZZY)
|
||||
&& !NM_FLAGS_ANY (prop_spec->flags, NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))
|
||||
continue;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
|
||||
&& !NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_INFERRABLE))
|
||||
continue;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)
|
||||
&& NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))
|
||||
continue;
|
||||
|
||||
if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
&& NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_SECRET))
|
||||
continue;
|
||||
|
||||
if (!NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags))
|
||||
if (_compare_property (sett_info, i, a, b, flags) == NM_TERNARY_FALSE)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
should_compare_prop (NMSetting *setting,
|
||||
const char *prop_name,
|
||||
NMSettingCompareFlags comp_flags,
|
||||
GParamFlags prop_flags)
|
||||
{
|
||||
/* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_FUZZY)
|
||||
&& (prop_flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)))
|
||||
return FALSE;
|
||||
|
||||
if ((comp_flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_flags & NM_SETTING_PARAM_INFERRABLE))
|
||||
return FALSE;
|
||||
|
||||
if ((comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY) && !(prop_flags & NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))
|
||||
return FALSE;
|
||||
|
||||
if (prop_flags & NM_SETTING_PARAM_SECRET) {
|
||||
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
return FALSE;
|
||||
|
||||
if ( NM_IS_SETTING_VPN (setting)
|
||||
&& g_strcmp0 (prop_name, NM_SETTING_VPN_SECRETS) == 0) {
|
||||
/* FIXME: NMSettingVPN:NM_SETTING_VPN_SECRETS has NM_SETTING_PARAM_SECRET.
|
||||
* nm_setting_get_secret_flags() quite possibly fails, but it might succeed if the
|
||||
* setting accidentally uses a key "secrets". */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
return FALSE;
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
|
||||
&& NM_IS_SETTING_CONNECTION (setting)
|
||||
&& !strcmp (prop_name, NM_SETTING_CONNECTION_ID))
|
||||
return FALSE;
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)
|
||||
&& NM_IS_SETTING_CONNECTION (setting)
|
||||
&& !strcmp (prop_name, NM_SETTING_CONNECTION_TIMESTAMP))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_setting_diff_add_result (GHashTable *results, const char *prop_name, NMSettingDiffResult r)
|
||||
{
|
||||
|
|
@ -1508,7 +1521,7 @@ nm_setting_diff (NMSetting *a,
|
|||
results_created = TRUE;
|
||||
}
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (a));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (a));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
const char *key;
|
||||
|
|
@ -1552,68 +1565,92 @@ nm_setting_diff (NMSetting *a,
|
|||
}
|
||||
} else {
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
|
||||
NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN;
|
||||
const NMSettInfoProperty *property_info;
|
||||
NMTernary compare_result;
|
||||
GParamSpec *prop_spec;
|
||||
|
||||
if (!prop_spec)
|
||||
compare_result = _compare_property (sett_info, i, a, b, flags);
|
||||
if (compare_result == NM_TERNARY_DEFAULT)
|
||||
continue;
|
||||
|
||||
/* Handle compare flags */
|
||||
if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags))
|
||||
continue;
|
||||
if (strcmp (prop_spec->name, NM_SETTING_NAME) == 0)
|
||||
continue;
|
||||
if ( NM_FLAGS_ANY (flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS
|
||||
| NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& b
|
||||
&& compare_result == NM_TERNARY_FALSE) {
|
||||
/* we have setting @b and the property is not the same. But we also are instructed
|
||||
* to ignore secrets based on the flags.
|
||||
*
|
||||
* Note that compare_property() called with two settings will ignore secrets
|
||||
* based on the flags, but it will do so if *both* settings have the flag we
|
||||
* look for. So that is symetric behavior and good.
|
||||
*
|
||||
* But for the purpose of diff(), we do a asymmetric comparison because and
|
||||
* we want to skip testing the property if setting @a alone indicates to do
|
||||
* so.
|
||||
*
|
||||
* We need to double-check whether the property should be ignored by
|
||||
* looking at @a alone. */
|
||||
if (_compare_property (sett_info, i, a, NULL, flags) == NM_TERNARY_DEFAULT)
|
||||
continue;
|
||||
}
|
||||
|
||||
compared_any = TRUE;
|
||||
|
||||
property_info = &sett_info->property_infos[i];
|
||||
prop_spec = property_info->param_spec;
|
||||
|
||||
if (b) {
|
||||
gboolean different;
|
||||
if (compare_result == NM_TERNARY_FALSE) {
|
||||
if (prop_spec) {
|
||||
gboolean a_is_default, b_is_default;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags);
|
||||
if (different) {
|
||||
gboolean a_is_default, b_is_default;
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
a_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
a_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
g_value_reset (&value);
|
||||
g_object_get_property (G_OBJECT (b), prop_spec->name, &value);
|
||||
b_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_reset (&value);
|
||||
g_object_get_property (G_OBJECT (b), prop_spec->name, &value);
|
||||
b_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) {
|
||||
if (!a_is_default)
|
||||
r |= a_result;
|
||||
if (!b_is_default)
|
||||
r |= b_result;
|
||||
} else {
|
||||
g_value_unset (&value);
|
||||
if (!NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)) {
|
||||
if (!a_is_default)
|
||||
r |= a_result;
|
||||
if (!b_is_default)
|
||||
r |= b_result;
|
||||
} else {
|
||||
r |= a_result | b_result;
|
||||
if (a_is_default)
|
||||
r |= a_result_default;
|
||||
if (b_is_default)
|
||||
r |= b_result_default;
|
||||
}
|
||||
} else
|
||||
r |= a_result | b_result;
|
||||
if (a_is_default)
|
||||
r |= a_result_default;
|
||||
if (b_is_default)
|
||||
r |= b_result_default;
|
||||
}
|
||||
}
|
||||
} else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0)
|
||||
r = a_result; /* only in A */
|
||||
else {
|
||||
GValue value = G_VALUE_INIT;
|
||||
if (prop_spec) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= a_result;
|
||||
else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)
|
||||
r |= a_result | a_result_default;
|
||||
|
||||
g_value_unset (&value);
|
||||
} else
|
||||
r |= a_result;
|
||||
else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)
|
||||
r |= a_result | a_result_default;
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) {
|
||||
diff_found = TRUE;
|
||||
_setting_diff_add_result (*results, prop_spec->name, r);
|
||||
_setting_diff_add_result (*results, property_info->name, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1662,7 +1699,7 @@ nm_setting_enumerate_values (NMSetting *setting,
|
|||
g_return_if_fail (NM_IS_SETTING (setting));
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
|
||||
if (sett_info->detail.gendata_info) {
|
||||
const char *const*names;
|
||||
|
|
@ -1742,16 +1779,21 @@ _nm_setting_aggregate (NMSetting *setting,
|
|||
if (NM_IS_SETTING_VPN (setting))
|
||||
return _nm_setting_vpn_aggregate (NM_SETTING_VPN (setting), type, arg);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
|
||||
const NMSettInfoProperty *property_info = &sett_info->property_infos[i];
|
||||
GParamSpec *prop_spec = property_info->param_spec;
|
||||
nm_auto_unset_gvalue GValue value = G_VALUE_INIT;
|
||||
NMSettingSecretFlags secret_flags;
|
||||
|
||||
if (!prop_spec)
|
||||
continue;
|
||||
if (!NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_SECRET))
|
||||
if ( !prop_spec
|
||||
|| !NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_SECRET)) {
|
||||
nm_assert (!nm_setting_get_secret_flags (setting, property_info->name, NULL, NULL));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* for the moment, all aggregate types only care about secrets. */
|
||||
nm_assert (nm_setting_get_secret_flags (setting, property_info->name, NULL, NULL));
|
||||
|
||||
switch (type) {
|
||||
|
||||
|
|
@ -1798,7 +1840,7 @@ _nm_setting_clear_secrets (NMSetting *setting)
|
|||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
|
||||
|
||||
|
|
@ -1875,7 +1917,7 @@ _nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
|||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (func != NULL, FALSE);
|
||||
|
||||
sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting));
|
||||
sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
|
||||
for (i = 0; i < sett_info->property_infos_len; i++) {
|
||||
GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
|
||||
|
||||
|
|
@ -1927,7 +1969,7 @@ update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError
|
|||
GParamSpec *prop_spec;
|
||||
GValue prop_value = { 0, };
|
||||
|
||||
property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), key);
|
||||
property = _nm_setting_class_get_property_info (NM_SETTING_GET_CLASS (setting), key);
|
||||
if (!property) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
@ -2034,7 +2076,7 @@ _nm_setting_property_is_regular_secret (NMSetting *setting,
|
|||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (secret_name);
|
||||
|
||||
property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), secret_name);
|
||||
property = _nm_setting_class_get_property_info (NM_SETTING_GET_CLASS (setting), secret_name);
|
||||
return property
|
||||
&& property->param_spec
|
||||
&& NM_FLAGS_HAS (property->param_spec->flags, NM_SETTING_PARAM_SECRET);
|
||||
|
|
@ -2049,7 +2091,7 @@ _nm_setting_property_is_regular_secret_flags (NMSetting *setting,
|
|||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (secret_flags_name);
|
||||
|
||||
property = _nm_sett_info_property_get (NM_SETTING_GET_CLASS (setting), secret_flags_name);
|
||||
property = _nm_setting_class_get_property_info (NM_SETTING_GET_CLASS (setting), secret_flags_name);
|
||||
return property
|
||||
&& property->param_spec
|
||||
&& !NM_FLAGS_HAS (property->param_spec->flags, NM_SETTING_PARAM_SECRET)
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ typedef gboolean (*NMSettingClearSecretsWithFlagsFn) (NMSetting *setting,
|
|||
gpointer user_data);
|
||||
|
||||
struct _NMMetaSettingInfo;
|
||||
struct _NMSettInfoSetting;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
|
@ -204,11 +205,18 @@ typedef struct {
|
|||
NMSettingClearSecretsWithFlagsFn func,
|
||||
gpointer user_data);
|
||||
|
||||
/* Returns TRUE if the given property contains the same value in both settings */
|
||||
gboolean (*compare_property) (NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags);
|
||||
/* compare_property() returns a ternary, where DEFAULT means that the property should not
|
||||
* be compared due to the compare @flags. A TRUE/FALSE result means that the property is
|
||||
* equal/not-equal.
|
||||
*
|
||||
* @other may be %NULL, in which case the function only determines whether
|
||||
* the setting should be compared (TRUE) or not (DEFAULT). */
|
||||
/*< private >*/
|
||||
NMTernary (*compare_property) (const struct _NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
NMSettingCompareFlags flags);
|
||||
|
||||
/*< private >*/
|
||||
const struct _NMMetaSettingInfo *setting_info;
|
||||
|
|
@ -270,7 +278,7 @@ typedef enum {
|
|||
NM_SETTING_DIFF_RESULT_IN_A = 0x00000001,
|
||||
NM_SETTING_DIFF_RESULT_IN_B = 0x00000002,
|
||||
NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004,
|
||||
NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000004,
|
||||
NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000008,
|
||||
} NMSettingDiffResult;
|
||||
|
||||
gboolean nm_setting_diff (NMSetting *a,
|
||||
|
|
|
|||
|
|
@ -3306,12 +3306,111 @@ test_data_compare_secrets_new (NMSettingSecretFlags secret_flags,
|
|||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
_test_compare_secrets_check_diff (NMSetting *a,
|
||||
NMSetting *b,
|
||||
NMSettingCompareFlags flags,
|
||||
gboolean exp_same_psk,
|
||||
gboolean exp_same_psk_flags)
|
||||
{
|
||||
gs_unref_hashtable GHashTable *h = NULL;
|
||||
NMSettingDiffResult _RESULT_IN_A = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
NMSettingDiffResult _RESULT_IN_B = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
gboolean invert_results;
|
||||
gboolean diff_result;
|
||||
NMSettingSecretFlags a_psk_flags = nm_setting_wireless_security_get_psk_flags (NM_SETTING_WIRELESS_SECURITY (a));
|
||||
NMSettingSecretFlags b_psk_flags = nm_setting_wireless_security_get_psk_flags (NM_SETTING_WIRELESS_SECURITY (b));
|
||||
const char *a_psk = nm_setting_wireless_security_get_psk (NM_SETTING_WIRELESS_SECURITY (a));
|
||||
const char *b_psk = nm_setting_wireless_security_get_psk (NM_SETTING_WIRELESS_SECURITY (b));
|
||||
|
||||
g_assert (NM_IS_SETTING_WIRELESS_SECURITY (a));
|
||||
g_assert (NM_IS_SETTING_WIRELESS_SECURITY (b));
|
||||
|
||||
invert_results = nmtst_get_rand_bool ();
|
||||
if (invert_results) {
|
||||
_RESULT_IN_A = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
_RESULT_IN_B = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
}
|
||||
|
||||
diff_result = nm_setting_diff (a, b, flags, invert_results, &h);
|
||||
|
||||
g_assert (exp_same_psk_flags == (a_psk_flags == b_psk_flags));
|
||||
|
||||
if (nm_streq0 (a_psk, b_psk))
|
||||
g_assert (exp_same_psk);
|
||||
else {
|
||||
if (flags == NM_SETTING_COMPARE_FLAG_EXACT)
|
||||
g_assert (!exp_same_psk);
|
||||
else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) {
|
||||
if ( !NM_FLAGS_HAS (a_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)
|
||||
&& !NM_FLAGS_HAS (b_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
g_assert (!exp_same_psk);
|
||||
else if ( !NM_FLAGS_HAS (a_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)
|
||||
&& NM_FLAGS_HAS (b_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
g_assert (!exp_same_psk);
|
||||
else
|
||||
g_assert (exp_same_psk);
|
||||
} else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) {
|
||||
if ( !NM_FLAGS_HAS (a_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
&& !NM_FLAGS_HAS (b_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED))
|
||||
g_assert (!exp_same_psk);
|
||||
else if ( !NM_FLAGS_HAS (a_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
&& NM_FLAGS_HAS (b_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED))
|
||||
g_assert (!exp_same_psk);
|
||||
else
|
||||
g_assert (exp_same_psk);
|
||||
} else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
g_assert (exp_same_psk);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_assert (diff_result == (exp_same_psk && exp_same_psk_flags));
|
||||
g_assert (diff_result == (!h));
|
||||
|
||||
if (!diff_result) {
|
||||
if (flags == NM_SETTING_COMPARE_FLAG_EXACT)
|
||||
g_assert (!exp_same_psk);
|
||||
else if ( NM_IN_SET (flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
|
||||
&& (a_psk_flags != b_psk_flags)
|
||||
&& nm_setting_wireless_security_get_psk_flags (NM_SETTING_WIRELESS_SECURITY (a)) == NM_SETTING_SECRET_FLAG_NONE)
|
||||
g_assert (!exp_same_psk);
|
||||
else
|
||||
g_assert (exp_same_psk);
|
||||
|
||||
g_assert ((!exp_same_psk) == g_hash_table_contains (h, NM_SETTING_WIRELESS_SECURITY_PSK));
|
||||
if (!exp_same_psk) {
|
||||
if (nm_setting_wireless_security_get_psk (NM_SETTING_WIRELESS_SECURITY (a)))
|
||||
g_assert_cmpint (GPOINTER_TO_UINT (g_hash_table_lookup (h, NM_SETTING_WIRELESS_SECURITY_PSK)), ==, _RESULT_IN_A);
|
||||
else
|
||||
g_assert_cmpint (GPOINTER_TO_UINT (g_hash_table_lookup (h, NM_SETTING_WIRELESS_SECURITY_PSK)), ==, _RESULT_IN_B);
|
||||
}
|
||||
|
||||
g_assert ((!exp_same_psk_flags) == g_hash_table_contains (h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS));
|
||||
if (!exp_same_psk_flags) {
|
||||
if (nm_setting_wireless_security_get_psk_flags (NM_SETTING_WIRELESS_SECURITY (a)) != NM_SETTING_SECRET_FLAG_NONE)
|
||||
g_assert_cmpint (GPOINTER_TO_UINT (g_hash_table_lookup (h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS)), ==, _RESULT_IN_A);
|
||||
else
|
||||
g_assert_cmpint (GPOINTER_TO_UINT (g_hash_table_lookup (h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS)), ==, _RESULT_IN_B);
|
||||
}
|
||||
|
||||
g_assert_cmpint (g_hash_table_size (h), ==, (!exp_same_psk) + (!exp_same_psk_flags));
|
||||
}
|
||||
|
||||
g_assert (diff_result == nm_setting_compare (a, b, flags));
|
||||
g_assert (diff_result == nm_setting_compare (b, a, flags));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_setting_compare_secrets (gconstpointer test_data)
|
||||
{
|
||||
const TestDataCompareSecrets *data = test_data;
|
||||
gs_unref_object NMSetting *old = NULL, *new = NULL;
|
||||
gboolean success;
|
||||
gs_unref_object NMConnection *conn_old = NULL;
|
||||
gs_unref_object NMConnection *conn_new = NULL;
|
||||
gs_unref_object NMSetting *old = NULL;
|
||||
gs_unref_object NMSetting *new = NULL;
|
||||
|
||||
/* Make sure that a connection with transient/unsaved secrets compares
|
||||
* successfully to the same connection without those secrets.
|
||||
|
|
@ -3324,17 +3423,45 @@ test_setting_compare_secrets (gconstpointer test_data)
|
|||
NULL);
|
||||
nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, data->secret_flags, NULL);
|
||||
|
||||
/* Clear the PSK from the duplicated setting */
|
||||
new = nm_setting_duplicate (old);
|
||||
if (data->remove_secret) {
|
||||
if (data->remove_secret)
|
||||
g_object_set (new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL);
|
||||
|
||||
success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||
g_assert (success == FALSE);
|
||||
g_assert ((!data->remove_secret) == nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
g_assert ((!data->remove_secret) == nm_setting_compare (new, old, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
|
||||
_test_compare_secrets_check_diff (old, new, NM_SETTING_COMPARE_FLAG_EXACT, !data->remove_secret, TRUE);
|
||||
_test_compare_secrets_check_diff (new, old, NM_SETTING_COMPARE_FLAG_EXACT, !data->remove_secret, TRUE);
|
||||
|
||||
g_assert (nm_setting_compare (old, new, data->comp_flags));
|
||||
g_assert (nm_setting_compare (new, old, data->comp_flags));
|
||||
|
||||
_test_compare_secrets_check_diff (old, new, data->comp_flags, TRUE, TRUE);
|
||||
_test_compare_secrets_check_diff (new, old, data->comp_flags, TRUE, TRUE);
|
||||
|
||||
/* OK. Try again, but this time not only change the secret, also let the secret flags differ... */
|
||||
if (data->secret_flags != NM_SETTING_SECRET_FLAG_NONE) {
|
||||
nm_setting_set_secret_flags (new, NM_SETTING_WIRELESS_SECURITY_PSK, NM_SETTING_SECRET_FLAG_NONE, NULL);
|
||||
|
||||
_test_compare_secrets_check_diff (old, new, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, FALSE);
|
||||
_test_compare_secrets_check_diff (new, old, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, FALSE);
|
||||
|
||||
_test_compare_secrets_check_diff (old, new, data->comp_flags, TRUE, FALSE);
|
||||
_test_compare_secrets_check_diff (new, old, data->comp_flags, FALSE, FALSE);
|
||||
|
||||
nm_setting_set_secret_flags (new, NM_SETTING_WIRELESS_SECURITY_PSK, data->secret_flags, NULL);
|
||||
}
|
||||
|
||||
success = nm_setting_compare (old, new, data->comp_flags);
|
||||
g_assert (success);
|
||||
conn_old = nmtst_create_minimal_connection ("test-compare-secrets", NULL, NM_SETTING_WIRELESS_SETTING_NAME, NULL);
|
||||
nm_connection_add_setting (conn_old, nm_setting_duplicate (old));
|
||||
conn_new = nm_simple_connection_new_clone (conn_old);
|
||||
nm_connection_add_setting (conn_new, nm_setting_duplicate (new));
|
||||
|
||||
g_assert ((!data->remove_secret) == nm_connection_compare (conn_old, conn_new, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
g_assert ((!data->remove_secret) == nm_connection_compare (conn_new, conn_old, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
|
||||
g_assert (nm_connection_compare (conn_old, conn_new, data->comp_flags));
|
||||
g_assert (nm_connection_compare (conn_new, conn_old, data->comp_flags));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -2033,7 +2033,7 @@ _log_connection_get_property (NMSetting *setting, const char *name)
|
|||
return g_strdup ("****");
|
||||
|
||||
if (!_nm_setting_get_property (setting, name, &val))
|
||||
g_return_val_if_reached (FALSE);
|
||||
return g_strdup ("<unknown>");
|
||||
|
||||
if (G_VALUE_HOLDS_STRING (&val)) {
|
||||
const char *val_s;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue