utils: fix check_possible_match() function

We can only allow possible match if all the differences are exceptions.
Before, we accepted the connection if an exception was found, but it is wrong
because there may be another difference (that is fatal).
This commit is contained in:
Jiří Klimeš
2014-04-09 13:48:27 +02:00
parent 583eba3828
commit d12b2079bf

View File

@@ -649,22 +649,47 @@ nm_utils_read_resolv_conf_nameservers (const char *rc_contents)
return nameservers; return nameservers;
} }
static GHashTable *
check_property_in_hash (GHashTable *hash,
const char *s_name,
const char *p_name)
{
GHashTable *props;
props = g_hash_table_lookup (hash, s_name);
if ( !props
|| !g_hash_table_lookup (props, p_name)) {
return NULL;
}
return props;
}
static void
remove_from_hash (GHashTable *s_hash,
GHashTable *p_hash,
const char *s_name,
const char *p_name)
{
g_hash_table_remove (p_hash, p_name);
if (g_hash_table_size (p_hash) == 0)
g_hash_table_remove (s_hash, s_name);
}
static gboolean static gboolean
check_ip6_method_link_local_auto (NMConnection *orig, check_ip6_method (NMConnection *orig,
NMConnection *candidate, NMConnection *candidate,
GHashTable *settings) GHashTable *settings)
{ {
GHashTable *props; GHashTable *props;
const char *orig_ip6_method, *candidate_ip6_method; const char *orig_ip6_method, *candidate_ip6_method;
NMSettingIP6Config *candidate_ip6; NMSettingIP6Config *candidate_ip6;
gboolean allow = FALSE;
props = g_hash_table_lookup (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME); props = check_property_in_hash (settings,
if ( !props NM_SETTING_IP6_CONFIG_SETTING_NAME,
|| (g_hash_table_size (props) != 1) NM_SETTING_IP6_CONFIG_METHOD);
|| !g_hash_table_lookup (props, NM_SETTING_IP6_CONFIG_METHOD)) { if (!props)
/* For now 'method' is the only difference we handle here */ return TRUE;
return FALSE;
}
/* If the original connection is 'link-local' and the candidate is both 'auto' /* If the original connection is 'link-local' and the candidate is both 'auto'
* and may-fail=TRUE, then the candidate is OK to use. may-fail is included * and may-fail=TRUE, then the candidate is OK to use. may-fail is included
@@ -679,60 +704,41 @@ check_ip6_method_link_local_auto (NMConnection *orig,
if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
&& strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0
&& (!candidate_ip6 || nm_setting_ip6_config_get_may_fail (candidate_ip6))) { && (!candidate_ip6 || nm_setting_ip6_config_get_may_fail (candidate_ip6))) {
return TRUE; allow = TRUE;
}
return FALSE;
}
static gboolean
check_ip6_method_link_local_ignore (NMConnection *orig,
NMConnection *candidate,
GHashTable *settings)
{
GHashTable *props;
const char *orig_ip6_method, *candidate_ip6_method;
props = g_hash_table_lookup (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME);
if ( !props
|| (g_hash_table_size (props) != 1)
|| !g_hash_table_lookup (props, NM_SETTING_IP6_CONFIG_METHOD)) {
/* We only handle ipv6 'method' here */
return FALSE;
} }
/* If the original connection method is 'link-local' and the candidate method /* If the original connection method is 'link-local' and the candidate method
* is 'ignore' we can take the connection, because NM didn't simply take care * is 'ignore' we can take the connection, because NM didn't simply take care
* of IPv6. * of IPv6.
*/ */
orig_ip6_method = nm_utils_get_ip_config_method (orig, NM_TYPE_SETTING_IP6_CONFIG);
candidate_ip6_method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG);
if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
&& strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
return TRUE; allow = TRUE;
} }
return FALSE; if (allow) {
remove_from_hash (settings, props,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_METHOD);
}
return allow;
} }
static gboolean static gboolean
check_ip4_method_disabled_auto (NMConnection *orig, check_ip4_method (NMConnection *orig,
NMConnection *candidate, NMConnection *candidate,
GHashTable *settings, GHashTable *settings,
gboolean device_has_carrier) gboolean device_has_carrier)
{ {
GHashTable *props; GHashTable *props;
const char *orig_ip4_method, *candidate_ip4_method; const char *orig_ip4_method, *candidate_ip4_method;
NMSettingIP4Config *candidate_ip4; NMSettingIP4Config *candidate_ip4;
props = g_hash_table_lookup (settings, NM_SETTING_IP4_CONFIG_SETTING_NAME); props = check_property_in_hash (settings,
if ( !props NM_SETTING_IP4_CONFIG_SETTING_NAME,
|| (g_hash_table_size (props) != 1) NM_SETTING_IP4_CONFIG_METHOD);
|| !g_hash_table_lookup (props, NM_SETTING_IP4_CONFIG_METHOD)) { if (!props)
/* For now 'method' is the only difference we handle here */ return TRUE;
return FALSE;
}
/* If the original connection is 'disabled' (device had no IP addresses) /* If the original connection is 'disabled' (device had no IP addresses)
* but it has no carrier, that most likely means that IP addressing could * but it has no carrier, that most likely means that IP addressing could
@@ -747,9 +753,11 @@ check_ip4_method_disabled_auto (NMConnection *orig,
&& strcmp (candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0 && strcmp (candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0
&& (!candidate_ip4 || nm_setting_ip4_config_get_may_fail (candidate_ip4)) && (!candidate_ip4 || nm_setting_ip4_config_get_may_fail (candidate_ip4))
&& (device_has_carrier == FALSE)) { && (device_has_carrier == FALSE)) {
remove_from_hash (settings, props,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP4_CONFIG_METHOD);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
@@ -762,13 +770,11 @@ check_connection_interface_name (NMConnection *orig,
const char *orig_ifname, *cand_ifname; const char *orig_ifname, *cand_ifname;
NMSettingConnection *s_con_orig, *s_con_cand; NMSettingConnection *s_con_orig, *s_con_cand;
props = g_hash_table_lookup (settings, NM_SETTING_CONNECTION_SETTING_NAME); props = check_property_in_hash (settings,
if ( !props NM_SETTING_CONNECTION_SETTING_NAME,
|| (g_hash_table_size (props) != 1) NM_SETTING_CONNECTION_INTERFACE_NAME);
|| !g_hash_table_lookup (props, NM_SETTING_CONNECTION_INTERFACE_NAME)) { if (!props)
/* We only handle 'interface-name' here. */ return TRUE;
return FALSE;
}
/* If one of the interface name is NULL, we accept that connection */ /* If one of the interface name is NULL, we accept that connection */
s_con_orig = nm_connection_get_setting_connection (orig); s_con_orig = nm_connection_get_setting_connection (orig);
@@ -776,9 +782,12 @@ check_connection_interface_name (NMConnection *orig,
orig_ifname = nm_setting_connection_get_interface_name (s_con_orig); orig_ifname = nm_setting_connection_get_interface_name (s_con_orig);
cand_ifname = nm_setting_connection_get_interface_name (s_con_cand); cand_ifname = nm_setting_connection_get_interface_name (s_con_cand);
if (!orig_ifname || !cand_ifname) if (!orig_ifname || !cand_ifname) {
remove_from_hash (settings, props,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME);
return TRUE; return TRUE;
}
return FALSE; return FALSE;
} }
@@ -790,19 +799,19 @@ check_possible_match (NMConnection *orig,
{ {
g_return_val_if_fail (settings != NULL, NULL); g_return_val_if_fail (settings != NULL, NULL);
if (check_ip6_method_link_local_auto (orig, candidate, settings)) if (!check_ip6_method (orig, candidate, settings))
return candidate; return NULL;
if (check_ip6_method_link_local_ignore (orig, candidate, settings)) if (!check_ip4_method (orig, candidate, settings, device_has_carrier))
return candidate; return NULL;
if (check_ip4_method_disabled_auto (orig, candidate, settings, device_has_carrier)) if (!check_connection_interface_name (orig, candidate, settings))
return candidate; return NULL;
if (check_connection_interface_name (orig, candidate, settings)) if (g_hash_table_size (settings) == 0)
return candidate; return candidate;
else
return NULL; return NULL;
} }
/** /**