Merge branch 'th/bgo696936_normalize_settings'

https://bugzilla.gnome.org/show_bug.cgi?id=696936

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-08-22 15:30:40 +02:00
commit fdef81207f
45 changed files with 1699 additions and 604 deletions

View file

@ -31,7 +31,6 @@
#include "nm-dbus-glib-types.h"
#include "nm-dispatcher-api.h"
#include "nm-utils.h"
#include "nm-utils-private.h"
/*******************************************/

View file

@ -33,7 +33,6 @@
#include <glib/gi18n-lib.h>
#include <dbus/dbus-glib.h>
#include <NetworkManager.h>
#include <nm-utils-private.h>
#include "nmt-route-table.h"
#include "nmt-route-entry.h"

View file

@ -32,6 +32,7 @@ CFILE_GLOB=$(top_srcdir)/libnm-core/*.c $(top_srcdir)/libnm/*.c
IGNORE_HFILES= \
crypto.h \
nm-dbus-helpers-private.h \
nm-core-internal.h \
nm-device-private.h \
nm-object-cache.h \
nm-object-private.h \

View file

@ -124,4 +124,29 @@ __nmtst_g_test_skip (const gchar *msg)
}
#define g_test_skip __nmtst_g_test_skip
/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */
inline static void
__g_test_add_data_func_full (const char *testpath,
gpointer test_data,
GTestDataFunc test_func,
GDestroyNotify data_free_func)
{
#if GLIB_CHECK_VERSION (2, 34, 0)
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_test_add_data_func_full (testpath, test_data, test_func, data_free_func);
G_GNUC_END_IGNORE_DEPRECATIONS
#else
g_return_if_fail (testpath != NULL);
g_return_if_fail (testpath[0] == '/');
g_return_if_fail (test_func != NULL);
g_test_add_vtable (testpath, 0, test_data, NULL,
(GTestFixtureFunc) test_func,
(GTestFixtureFunc) data_free_func);
#endif
}
#define g_test_add_data_func_full __g_test_add_data_func_full
#endif /* __NM_GLIB_COMPAT_H__ */

View file

@ -36,6 +36,30 @@
#include "gsystem-local-alloc.h"
/*******************************************************************************/
/* general purpose functions that have no dependency on other nmtst functions */
inline static void
nmtst_assert_error (GError *error,
GQuark expect_error_domain,
gint expect_error_code,
const char *expect_error_pattern)
{
if (expect_error_domain)
g_assert_error (error, expect_error_domain, expect_error_code);
else
g_assert (error);
g_assert (error->message);
if ( expect_error_pattern
&& !g_pattern_match_simple (expect_error_pattern, error->message)) {
g_error ("error message does not have expected pattern '%s'. Instead it is '%s' (%s, %d)",
expect_error_pattern, error->message, g_quark_to_string (error->domain), error->code);
}
}
/*******************************************************************************/
struct __nmtst_internal
{
GRand *rand0;
@ -724,6 +748,215 @@ nmtst_create_minimal_connection (const char *id, const char *uuid, const char *t
return con;
}
inline static gboolean
_nmtst_connection_normalize_v (NMConnection *connection, va_list args)
{
GError *error = NULL;
gboolean success;
gboolean was_modified = FALSE;
GHashTable *parameters = NULL;
const char *p_name;
g_assert (NM_IS_CONNECTION (connection));
while ((p_name = va_arg (args, const char *))) {
if (!parameters)
parameters = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (parameters, (gpointer *) p_name, va_arg (args, gpointer));
}
success = nm_connection_normalize (connection,
parameters,
&was_modified,
&error);
g_assert_no_error (error);
g_assert (success);
if (parameters)
g_hash_table_destroy (parameters);
return was_modified;
}
inline static gboolean
_nmtst_connection_normalize (NMConnection *connection, ...)
{
gboolean was_modified;
va_list args;
va_start (args, connection);
was_modified = _nmtst_connection_normalize_v (connection, args);
va_end (args);
return was_modified;
}
#define nmtst_connection_normalize(connection, ...) \
_nmtst_connection_normalize(connection, ##__VA_ARGS__, NULL)
inline static NMConnection *
_nmtst_connection_duplicate_and_normalize (NMConnection *connection, ...)
{
gboolean was_modified;
va_list args;
g_assert (NM_IS_CONNECTION (connection));
connection = nm_simple_connection_new_clone (connection);
va_start (args, connection);
was_modified = _nmtst_connection_normalize_v (connection, args);
va_end (args);
return connection;
}
#define nmtst_connection_duplicate_and_normalize(connection, ...) \
_nmtst_connection_duplicate_and_normalize(connection, ##__VA_ARGS__, NULL)
inline static void
nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnection *b, gboolean normalize_b)
{
gboolean compare;
gs_unref_object NMConnection *a2 = NULL;
gs_unref_object NMConnection *b2 = NULL;
GHashTable *out_settings = NULL;
g_assert (NM_IS_CONNECTION (a));
g_assert (NM_IS_CONNECTION (b));
if (normalize_a)
a = a2 = nmtst_connection_duplicate_and_normalize (a);
if (normalize_b)
b = b2 = nmtst_connection_duplicate_and_normalize (b);
compare = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings);
if (!compare && out_settings) {
const char *name, *pname;
GHashTable *setting;
GHashTableIter iter, iter2;
g_hash_table_iter_init (&iter, out_settings);
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting)) {
__NMTST_LOG (g_message, ">>> differences in setting '%s':", name);
g_hash_table_iter_init (&iter2, out_settings);
while (g_hash_table_iter_next (&iter2, (gpointer *) &pname, NULL))
__NMTST_LOG (g_message, ">>> differences in setting '%s.%s':", name, pname);
}
}
g_assert (compare);
g_assert (!out_settings);
compare = nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT);
g_assert (compare);
}
inline static void
nmtst_assert_connection_verifies_without_normalization (NMConnection *con)
{
/* assert that the connection verifies and does not need any normalization */
GError *error = NULL;
gboolean success;
gboolean was_modified = FALSE;
gs_unref_object NMConnection *clone = NULL;
g_assert (NM_IS_CONNECTION (con));
clone = nm_simple_connection_new_clone (con);
success = nm_connection_verify (con, &error);
g_assert_no_error (error);
g_assert (success);
success = nm_connection_normalize (con, NULL, &was_modified, &error);
g_assert_no_error (error);
g_assert (success);
g_assert (!was_modified);
nmtst_assert_connection_equals (con, FALSE, clone, FALSE);
}
inline static void
nmtst_assert_connection_verifies_and_normalizable (NMConnection *con)
{
/* assert that the connection does verify, but normalization still modifies it */
GError *error = NULL;
gboolean success;
gboolean was_modified = FALSE;
g_assert (NM_IS_CONNECTION (con));
success = nm_connection_verify (con, &error);
g_assert_no_error (error);
g_assert (success);
g_clear_error (&error);
success = nm_connection_normalize (con, NULL, &was_modified, &error);
g_assert_no_error (error);
g_assert (success);
g_assert (was_modified);
/* again! */
nmtst_assert_connection_verifies_without_normalization (con);
}
inline static void
nmtst_assert_connection_verifies_after_normalization (NMConnection *con,
GQuark expect_error_domain,
gint expect_error_code)
{
/* assert that the connection does not verify, but normalization does fix it */
GError *error = NULL;
gboolean success;
gboolean was_modified = FALSE;
g_assert (NM_IS_CONNECTION (con));
success = nm_connection_verify (con, &error);
nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
g_assert (!success);
g_clear_error (&error);
success = nm_connection_normalize (con, NULL, &was_modified, &error);
g_assert_no_error (error);
g_assert (success);
g_assert (was_modified);
/* again! */
nmtst_assert_connection_verifies_without_normalization (con);
}
inline static void
nmtst_assert_connection_unnormalizable (NMConnection *con,
GQuark expect_error_domain,
gint expect_error_code)
{
/* assert that the connection does not verify, and it cannot be fixed by normalization */
GError *error = NULL;
gboolean success;
gboolean was_modified = FALSE;
gs_unref_object NMConnection *clone = NULL;
g_assert (NM_IS_CONNECTION (con));
clone = nm_simple_connection_new_clone (con);
success = nm_connection_verify (con, &error);
nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
g_assert (!success);
g_clear_error (&error);
success = nm_connection_normalize (con, NULL, &was_modified, &error);
nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
g_assert (!success);
g_assert (!was_modified);
g_clear_error (&error);
nmtst_assert_connection_equals (con, FALSE, clone, FALSE);
}
#endif
#endif /* __NM_TEST_UTILS_H__ */

View file

@ -43,6 +43,7 @@ libnm_core_headers = \
libnm_core_private_headers = \
$(core)/crypto.h \
$(core)/nm-core-internal.h \
$(core)/nm-param-spec-specialized.h \
$(core)/nm-setting-private.h \
$(core)/nm-utils-private.h

View file

@ -25,7 +25,7 @@
#include <dbus/dbus-glib.h>
#include <string.h>
#include "nm-connection.h"
#include "nm-utils.h"
#include "nm-utils-internal.h"
#include "nm-dbus-glib-types.h"
#include "nm-setting-private.h"
@ -128,12 +128,23 @@ setting_changed_cb (NMSetting *setting,
g_signal_emit (self, signals[CHANGED], 0);
}
static gboolean
_setting_release (gpointer key, gpointer value, gpointer user_data)
{
g_signal_handlers_disconnect_by_func (user_data, setting_changed_cb, value);
return TRUE;
}
static void
_nm_connection_add_setting (NMConnection *connection, NMSetting *setting)
{
g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings,
(gpointer) G_OBJECT_TYPE_NAME (setting),
setting);
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
const char *name = G_OBJECT_TYPE_NAME (setting);
NMSetting *s_old;
if ((s_old = g_hash_table_lookup (priv->settings, (gpointer) name)))
g_signal_handlers_disconnect_by_func (s_old, setting_changed_cb, connection);
g_hash_table_insert (priv->settings, (gpointer) name, setting);
/* Listen for property changes so we can emit the 'changed' signal */
g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection);
}
@ -290,7 +301,7 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error)
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
if ((changed = g_hash_table_size (priv->settings) > 0))
g_hash_table_remove_all (priv->settings);
g_hash_table_foreach_remove (priv->settings, _setting_release, connection);
g_hash_table_iter_init (&iter, new);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
@ -376,7 +387,7 @@ nm_connection_replace_settings_from_connection (NMConnection *connection,
priv = NM_CONNECTION_GET_PRIVATE (connection);
if ((changed = g_hash_table_size (priv->settings) > 0))
g_hash_table_remove_all (priv->settings);
g_hash_table_foreach_remove (priv->settings, _setting_release, connection);
if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (new_connection)->settings)) {
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (new_connection)->settings);
@ -569,6 +580,81 @@ _normalize_virtual_iface_name (NMConnection *self)
return was_modified;
}
static gboolean
_normalize_connection_type (NMConnection *self)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (self);
NMSetting *s_base = NULL;
const char *type;
GSList *all_settings;
type = nm_setting_connection_get_connection_type (s_con);
if (type) {
s_base = nm_connection_get_setting_by_name (self, type);
if (!s_base) {
GType base_type = nm_setting_lookup_type (type);
g_return_val_if_fail (base_type, FALSE);
nm_connection_add_setting (self, g_object_new (base_type, NULL));
return TRUE;
}
} else {
all_settings = _nm_utils_hash_values_to_slist (NM_CONNECTION_GET_PRIVATE (self)->settings);
s_base = _nm_setting_find_in_list_base_type (all_settings);
g_return_val_if_fail (s_base, FALSE);
type = nm_setting_get_name (s_base);
g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL);
g_slist_free (all_settings);
return TRUE;
}
return FALSE;
}
static gboolean
_normalize_connection_slave_type (NMConnection *self)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (self);
const char *slave_type, *port_type;
GSList *all_settings;
if (!s_con)
return FALSE;
if (!nm_setting_connection_get_master (s_con))
return FALSE;
slave_type = nm_setting_connection_get_slave_type (s_con);
if (slave_type) {
if ( _nm_setting_slave_type_is_valid (slave_type, &port_type)
&& port_type) {
NMSetting *s_port;
s_port = nm_connection_get_setting_by_name (self, port_type);
if (!s_port) {
GType p_type = nm_setting_lookup_type (port_type);
g_return_val_if_fail (p_type, FALSE);
nm_connection_add_setting (self, g_object_new (p_type, NULL));
return TRUE;
}
}
} else {
all_settings = _nm_utils_hash_values_to_slist (NM_CONNECTION_GET_PRIVATE (self)->settings);
if ((slave_type = _nm_setting_slave_type_detect_from_settings (all_settings, NULL))) {
g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL);
g_slist_free (all_settings);
return TRUE;
}
g_slist_free (all_settings);
}
return FALSE;
}
static gboolean
_normalize_ip_config (NMConnection *self, GHashTable *parameters)
{
@ -624,6 +710,30 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
}
}
static gboolean
_normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters)
{
NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband (self);
if (s_infini) {
const char *transport_mode = nm_setting_infiniband_get_transport_mode (s_infini);
guint32 max_mtu = 0;
if (transport_mode) {
if (!strcmp (transport_mode, "datagram"))
max_mtu = 2044;
else if (!strcmp (transport_mode, "connected"))
max_mtu = 65520;
if (max_mtu && nm_setting_infiniband_get_mtu (s_infini) > max_mtu) {
g_object_set (s_infini, NM_SETTING_INFINIBAND_MTU, max_mtu, NULL);
return TRUE;
}
}
}
return FALSE;
}
/**
* nm_connection_verify:
* @connection: the #NMConnection to verify
@ -666,21 +776,11 @@ _nm_connection_verify (NMConnection *connection, GError **error)
gpointer value;
GSList *all_settings = NULL, *setting_i;
NMSettingVerifyResult success = NM_SETTING_VERIFY_ERROR;
NMSetting *base;
const char *ctype;
GError *normalizable_error = NULL;
NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS;
if (error)
g_return_val_if_fail (*error == NULL, NM_SETTING_VERIFY_ERROR);
if (!NM_IS_CONNECTION (connection)) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_UNKNOWN,
"invalid connection; failed verification");
g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
}
g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
g_return_val_if_fail (!error || !*error, NM_SETTING_VERIFY_ERROR);
priv = NM_CONNECTION_GET_PRIVATE (connection);
@ -698,10 +798,7 @@ _nm_connection_verify (NMConnection *connection, GError **error)
g_hash_table_iter_init (&iter, priv->settings);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
/* Order NMSettingConnection so that it will be verified first.
* The reason is, that NMSettingConnection:verify() modifies the connection
* by setting NMSettingConnection:interface_name. So we want to call that
* verify() first, because the order can affect the outcome.
* Another reason is, that errors in this setting might be more fundamental
* The reason is, that errors in this setting might be more fundamental
* and should be checked and reported with higher priority.
* Another reason is, that some settings look especially at the
* NMSettingConnection, so they find it first in the all_settings list. */
@ -747,36 +844,6 @@ _nm_connection_verify (NMConnection *connection, GError **error)
}
g_slist_free (all_settings);
/* Now make sure the given 'type' setting can actually be the base setting
* of the connection. Can't have type=ppp for example.
*/
ctype = nm_setting_connection_get_connection_type (s_con);
if (!ctype) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
"connection type missing");
goto EXIT;
}
base = nm_connection_get_setting_by_name (connection, ctype);
if (!base) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
"base setting GType not found");
goto EXIT;
}
if (!_nm_setting_is_base_type (base)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
"connection type '%s' is not a base type",
ctype);
goto EXIT;
}
s_ip4 = nm_connection_get_setting_ip4_config (connection);
s_ip6 = nm_connection_get_setting_ip6_config (connection);
@ -856,7 +923,16 @@ nm_connection_normalize (NMConnection *connection,
success == NM_SETTING_VERIFY_SUCCESS) {
if (normalizable_error)
g_propagate_error (error, normalizable_error);
goto EXIT;
if (modified)
*modified = FALSE;
if (success == NM_SETTING_VERIFY_ERROR && error && !*error) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_UNKNOWN,
_("Unexpected failure to verify the connection"));
g_return_val_if_reached (FALSE);
}
return success == NM_SETTING_VERIFY_SUCCESS;
}
g_assert (success == NM_SETTING_VERIFY_NORMALIZABLE || success == NM_SETTING_VERIFY_NORMALIZABLE_ERROR);
g_clear_error (&normalizable_error);
@ -865,23 +941,35 @@ nm_connection_normalize (NMConnection *connection,
* We only do this, after verifying that the connection contains no un-normalizable
* errors, because in that case we rather fail without touching the settings. */
was_modified |= _normalize_connection_type (connection);
was_modified |= _normalize_virtual_iface_name (connection);
was_modified |= _normalize_connection_slave_type (connection);
was_modified |= _normalize_ip_config (connection, parameters);
was_modified |= _normalize_infiniband_mtu (connection, parameters);
/* Verify anew. */
success = _nm_connection_verify (connection, error);
/* we would expect, that after normalization, the connection can be verified. */
g_return_val_if_fail (success == NM_SETTING_VERIFY_SUCCESS, success);
/* we would expect, that the connection was modified during normalization. */
g_return_val_if_fail (was_modified, success);
EXIT:
if (modified)
*modified = was_modified;
return success == NM_SETTING_VERIFY_SUCCESS;
if (success != NM_SETTING_VERIFY_SUCCESS) {
/* we would expect, that after normalization, the connection can be verified.
* Also treat NM_SETTING_VERIFY_NORMALIZABLE as failure, because there is something
* odd going on. */
if (error && !*error) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_UNKNOWN,
_("Unexpected failure to normalize the connection"));
}
g_return_val_if_reached (FALSE);
}
/* we would expect, that the connection was modified during normalization. */
g_return_val_if_fail (was_modified, TRUE);
return TRUE;
}
/**
@ -1892,12 +1980,8 @@ static void
nm_connection_private_free (NMConnectionPrivate *priv)
{
NMConnection *self = priv->self;
GHashTableIter iter;
NMSetting *setting;
g_hash_table_iter_init (&iter, priv->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
g_signal_handlers_disconnect_by_func (setting, setting_changed_cb, self);
g_hash_table_foreach_remove (priv->settings, _setting_release, self);
g_hash_table_destroy (priv->settings);
g_slice_free (NMConnectionPrivate, priv);

View file

@ -0,0 +1,67 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* (C) Copyright 2014 Red Hat, Inc.
*/
#ifndef NM_CORE_NM_INTERNAL_H
#define NM_CORE_NM_INTERNAL_H
/* This header file contain functions that are provided as private API
* by libnm-core. It will contain functions to give privileged access to
* libnm-core. This can be useful for NetworkManager and libnm.so
* which both are special users of libnm-core.
* It also exposes some utility functions for reuse.
*
* These functions are not exported and are only available to components that link
* statically against libnm-core. This basically means libnm-core, libnm, NetworkManager
* and some test programs.
**/
#include <glib.h>
#include "nm-utils.h"
#include "nm-setting-ip4-config.h"
const char *_nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting,
guint32 i);
gboolean _nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting,
NMIP4Address *address,
const char *label);
/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated
* connection can be replaced by a already-defined connection. This flag only
* takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE
* flag.
*/
#define NM_SETTING_COMPARE_FLAG_INFERRABLE 0x80000000
#define NM_SETTING_SECRET_FLAGS_ALL \
(NM_SETTING_SECRET_FLAG_NONE | \
NM_SETTING_SECRET_FLAG_AGENT_OWNED | \
NM_SETTING_SECRET_FLAG_NOT_SAVED | \
NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
#endif

View file

@ -159,6 +159,32 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
if (all_settings) {
NMSettingConnection *s_con;
const char *slave_type;
s_con = NM_SETTING_CONNECTION (_nm_setting_find_in_list_required (all_settings,
NM_SETTING_CONNECTION_SETTING_NAME,
error, NULL, NULL));
if (!s_con)
return FALSE;
slave_type = nm_setting_connection_get_slave_type (s_con);
if ( slave_type
&& strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"),
NM_SETTING_BRIDGE_PORT_SETTING_NAME,
NM_SETTING_BRIDGE_SETTING_NAME,
slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
}
return TRUE;
}

View file

@ -735,13 +735,28 @@ nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting)
return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->gateway_ping_timeout;
}
static void
_set_error_missing_base_setting (GError **error, const char *type)
{
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND,
_("requires presence of '%s' setting in the connection"),
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
}
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
gboolean is_slave;
GSList *iter;
const char *slave_setting_type = NULL;
NMSetting *normerr_base_type = NULL;
const char *normerr_slave_setting_type = NULL;
const char *normerr_missing_slave_type = NULL;
const char *normerr_missing_slave_type_port = NULL;
gboolean normerr_base_setting = FALSE;
if (!priv->id) {
g_set_error_literal (error,
@ -750,7 +765,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID);
return FALSE;
} else if (!strlen (priv->id)) {
} else if (!priv->id[0]) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
@ -776,38 +791,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
/* FIXME: previously, verify() set the NMSettingConnection:interface_name property,
* thus modifying the setting. verify() should not do this, but keep this not to change
* behaviour.
*/
if (!priv->interface_name) {
for (iter = all_settings; iter; iter = iter->next) {
NMSetting *s_current = iter->data;
char *virtual_iface_name = NULL;
if (NM_IS_SETTING_BOND (s_current))
g_object_get (s_current, NM_SETTING_BOND_INTERFACE_NAME, &virtual_iface_name, NULL);
else if (NM_IS_SETTING_BRIDGE (s_current))
g_object_get (s_current, NM_SETTING_BRIDGE_INTERFACE_NAME, &virtual_iface_name, NULL);
else if (NM_IS_SETTING_TEAM (s_current))
g_object_get (s_current, NM_SETTING_TEAM_INTERFACE_NAME, &virtual_iface_name, NULL);
else if (NM_IS_SETTING_VLAN (s_current))
g_object_get (s_current, NM_SETTING_VLAN_INTERFACE_NAME, &virtual_iface_name, NULL);
/* For NMSettingInfiniband, virtual_iface_name has no backing field.
* No need to set the (unset) interface_name to the default value.
**/
if (virtual_iface_name) {
if (nm_utils_iface_valid_name (virtual_iface_name)) {
/* found a new interface name. */
priv->interface_name = virtual_iface_name;
break;
}
g_free (virtual_iface_name);
}
}
}
if (priv->interface_name) {
if (!nm_utils_iface_valid_name (priv->interface_name)) {
g_set_error (error,
@ -821,36 +804,71 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
}
if (!priv->type) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
} else if (!strlen (priv->type)) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
if (!(normerr_base_type = _nm_setting_find_in_list_base_type (all_settings))) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
} else {
GType base_type;
if (!priv->type[0]) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
base_type = nm_setting_lookup_type (priv->type);
if (base_type == G_TYPE_INVALID) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("connection type '%s' is not valid"),
priv->type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
if (!_nm_setting_type_is_base_type (base_type)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
_("connection type '%s' is not a valid base type"),
priv->type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
/* Make sure the corresponding 'type' item is present */
if ( all_settings
&& !nm_setting_find_in_list (all_settings, priv->type)) {
NMSetting *s_base;
GSList *all_settings2;
s_base = g_object_new (base_type, NULL);
all_settings2 = g_slist_prepend (all_settings, s_base);
normerr_base_setting = nm_setting_verify (s_base, all_settings2, NULL);
(void) g_slist_delete_link (all_settings2, all_settings2);
g_object_unref (s_base);
if (!normerr_base_setting) {
_set_error_missing_base_setting (error, priv->type);
return FALSE;
}
}
}
/* Make sure the corresponding 'type' item is present */
if (all_settings && !nm_setting_find_in_list (all_settings, priv->type)) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND,
_("requires presence of '%s' setting in the connection"),
priv->type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
is_slave = ( priv->slave_type
&& ( !strcmp (priv->slave_type, NM_SETTING_BOND_SETTING_NAME)
|| !strcmp (priv->slave_type, NM_SETTING_BRIDGE_SETTING_NAME)
|| !strcmp (priv->slave_type, NM_SETTING_TEAM_SETTING_NAME)));
is_slave = FALSE;
if (priv->slave_type)
is_slave = _nm_setting_slave_type_is_valid (priv->slave_type, &slave_setting_type);
if (priv->slave_type && !is_slave) {
g_set_error (error,
@ -858,7 +876,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("Unknown slave type '%s'"), priv->slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return NM_SETTING_VERIFY_ERROR;
return FALSE;
}
if (is_slave) {
@ -868,19 +886,69 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("Slave connections need a valid '" NM_SETTING_CONNECTION_MASTER "' property"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER);
return NM_SETTING_VERIFY_ERROR;
return FALSE;
}
if ( slave_setting_type
&& all_settings /* only check for an existing slave-setting when having @all_settings */
&& !nm_setting_find_in_list (all_settings, slave_setting_type))
normerr_slave_setting_type = slave_setting_type;
} else {
if (priv->master) {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("Cannot set '" NM_SETTING_CONNECTION_MASTER "' without '" NM_SETTING_CONNECTION_SLAVE_TYPE "'"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return NM_SETTING_VERIFY_ERROR;
const char *slave_type;
NMSetting *s_port;
if ( all_settings
&& (slave_type = _nm_setting_slave_type_detect_from_settings (all_settings, &s_port))) {
normerr_missing_slave_type = slave_type;
normerr_missing_slave_type_port = nm_setting_get_name (s_port);
} else {
g_set_error_literal (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("Cannot set '" NM_SETTING_CONNECTION_MASTER "' without '" NM_SETTING_CONNECTION_SLAVE_TYPE "'"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
}
}
/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
if (normerr_base_type) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("property type should be set to '%s'"),
nm_setting_get_name (normerr_base_type));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (normerr_base_setting) {
_set_error_missing_base_setting (error, priv->type);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (normerr_slave_setting_type) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_SLAVE_SETTING_NOT_FOUND,
_("slave-type '%s' requires a '%s' setting in the connection"),
priv->slave_type, normerr_slave_setting_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (normerr_missing_slave_type) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("Detect a slave connection with '" NM_SETTING_CONNECTION_MASTER "' set and a port type '%s'. '" NM_SETTING_CONNECTION_SLAVE_TYPE "' should be set to '%s'"),
normerr_missing_slave_type_port, normerr_missing_slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
return TRUE;
}

View file

@ -52,6 +52,8 @@ G_BEGIN_DECLS
* #NMSettingConnection:type property was not present in the #NMConnection
* @NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED: ip configuration is not
* allowed to be present.
* @NM_SETTING_CONNECTION_ERROR_SLAVE_SETTING_NOT_FOUND: the mandatory #NMSetting
* object for the slave is missing. The slave type depends on #NMSettingConnection:slave-type
*
* Describes errors that may result from operations involving a
* #NMSettingConnection.
@ -64,6 +66,7 @@ typedef enum
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, /*< nick=MissingProperty >*/
NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND, /*< nick=TypeSettingNotFound >*/
NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED, /*< nick=IpConfigNotAllowed >*/
NM_SETTING_CONNECTION_ERROR_SLAVE_SETTING_NOT_FOUND, /*< nick=SlaveSettingNotFound >*/
} NMSettingConnectionError;
#define NM_SETTING_CONNECTION_ERROR nm_setting_connection_error_quark ()

View file

@ -194,6 +194,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
{
NMSettingConnection *s_con;
NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);
guint32 normerr_max_mtu = 0;
if (priv->mac_address && priv->mac_address->len != INFINIBAND_ALEN) {
g_set_error_literal (error,
@ -206,10 +207,10 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
if (!g_strcmp0 (priv->transport_mode, "datagram")) {
if (priv->mtu > 2044)
priv->mtu = 2044;
normerr_max_mtu = 2044;
} else if (!g_strcmp0 (priv->transport_mode, "connected")) {
if (priv->mtu > 65520)
priv->mtu = 65520;
normerr_max_mtu = 65520;
} else {
g_set_error_literal (error,
NM_SETTING_INFINIBAND_ERROR,
@ -287,6 +288,18 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
}
}
/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
if (normerr_max_mtu > 0) {
g_set_error (error,
NM_SETTING_INFINIBAND_ERROR,
NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
_("mtu for transport mode '%s' can be at most %d but it is %d"),
priv->transport_mode, normerr_max_mtu, priv->mtu);
g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
return TRUE;
}

View file

@ -30,6 +30,7 @@
#include "nm-dbus-glib-types.h"
#include "nm-glib-compat.h"
#include "nm-setting-private.h"
#include "nm-core-internal.h"
/**
@ -435,7 +436,7 @@ nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i)
}
const char *
nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i)
_nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i)
{
NMSettingIP4ConfigPrivate *priv;
@ -462,13 +463,13 @@ gboolean
nm_setting_ip4_config_add_address (NMSettingIP4Config *setting,
NMIP4Address *address)
{
return nm_setting_ip4_config_add_address_with_label (setting, address, NULL);
return _nm_setting_ip4_config_add_address_with_label (setting, address, NULL);
}
gboolean
nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting,
NMIP4Address *address,
const char *label)
_nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting,
NMIP4Address *address,
const char *label)
{
NMSettingIP4ConfigPrivate *priv;
NMIP4Address *copy;

View file

@ -24,11 +24,7 @@
#include "nm-setting.h"
#include "nm-glib-compat.h"
#define NM_SETTING_SECRET_FLAGS_ALL \
(NM_SETTING_SECRET_FLAG_NONE | \
NM_SETTING_SECRET_FLAG_AGENT_OWNED | \
NM_SETTING_SECRET_FLAG_NOT_SAVED | \
NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
#include "nm-core-internal.h"
/**
* NMSettingVerifyResult:
@ -73,13 +69,6 @@ gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting,
gpointer user_data);
/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated
* connection can be replaced by a already-defined connection. This flag only
* takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE
* flag.
*/
#define NM_SETTING_COMPARE_FLAG_INFERRABLE 0x80000000
/* The property of the #NMSetting should be considered during comparisons that
* use the %NM_SETTING_COMPARE_FLAG_INFERRABLE flag. Properties that don't have
* this flag, are ignored when doing an infrerrable comparison. This flag should
@ -101,10 +90,11 @@ static void __attribute__((constructor)) register_setting (void) \
NMSetting *nm_setting_find_in_list (GSList *settings_list, const char *setting_name);
/* Private NMSettingIP4Config methods */
#include "nm-setting-ip4-config.h"
const char *nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i);
gboolean nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting, NMIP4Address *address, const char *label);
NMSetting * _nm_setting_find_in_list_required (GSList *all_settings,
const char *setting_name,
GError **error,
const char *error_prefix_setting_name,
const char *error_prefix_property_name);
NMSettingVerifyResult _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
gboolean allow_missing,
@ -120,4 +110,8 @@ NMSettingVerifyResult _nm_setting_verify (NMSetting *setting,
GSList *all_settings,
GError **error);
NMSetting *_nm_setting_find_in_list_base_type (GSList *all_settings);
gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type);
const char * _nm_setting_slave_type_detect_from_settings (GSList *all_settings, NMSetting **out_s_port);
#endif /* NM_SETTING_PRIVATE_H */

View file

@ -103,6 +103,30 @@ nm_setting_team_port_get_config (NMSettingTeamPort *setting)
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
if (all_settings) {
NMSettingConnection *s_con;
const char *slave_type;
s_con = NM_SETTING_CONNECTION (_nm_setting_find_in_list_required (all_settings,
NM_SETTING_CONNECTION_SETTING_NAME,
error, NULL, NULL));
if (!s_con)
return FALSE;
slave_type = nm_setting_connection_get_slave_type (s_con);
if ( slave_type
&& strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME)) {
g_set_error (error,
NM_SETTING_CONNECTION_ERROR,
NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"),
NM_SETTING_TEAM_PORT_SETTING_NAME,
NM_SETTING_TEAM_SETTING_NAME,
slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
}
return TRUE;
}

View file

@ -566,7 +566,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
/* If parent is NULL, the parent must be specified via
* NMSettingWired:mac-address.
*/
if (!s_wired || !nm_setting_wired_get_mac_address (s_wired)) {
if ( all_settings
&& (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
g_set_error (error,
NM_SETTING_VLAN_ERROR,
NM_SETTING_VLAN_ERROR_MISSING_PROPERTY,

View file

@ -288,6 +288,88 @@ _nm_setting_compare_priority (gconstpointer a, gconstpointer b)
/*************************************************************/
gboolean
_nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type)
{
const char *port_type = NULL;
gboolean found = TRUE;
if (!slave_type)
found = FALSE;
else if (!strcmp (slave_type, NM_SETTING_BOND_SETTING_NAME))
;
else if (!strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME))
port_type = NM_SETTING_BRIDGE_PORT_SETTING_NAME;
else if (!strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME))
port_type = NM_SETTING_TEAM_PORT_SETTING_NAME;
else
found = FALSE;
if (out_port_type)
*out_port_type = port_type;
return found;
}
NMSetting *
_nm_setting_find_in_list_base_type (GSList *all_settings)
{
GSList *iter;
NMSetting *setting = NULL;
for (iter = all_settings; iter; iter = iter->next) {
NMSetting *s_iter = NM_SETTING (iter->data);
if (!_nm_setting_is_base_type (s_iter))
continue;
if (setting) {
/* FIXME: currently, if there is more than one matching base type,
* we cannot detect the base setting.
* See: https://bugzilla.gnome.org/show_bug.cgi?id=696936#c8 */
return NULL;
}
setting = s_iter;
}
return setting;
}
const char *
_nm_setting_slave_type_detect_from_settings (GSList *all_settings, NMSetting **out_s_port)
{
GSList *iter;
const char *slave_type = NULL;
NMSetting *s_port = NULL;
for (iter = all_settings; iter; iter = iter->next) {
NMSetting *s_iter = NM_SETTING (iter->data);
const char *name = nm_setting_get_name (s_iter);
const char *i_slave_type = NULL;
if (!strcmp (name, NM_SETTING_BRIDGE_PORT_SETTING_NAME))
i_slave_type = NM_SETTING_BRIDGE_SETTING_NAME;
else if (!strcmp (name, NM_SETTING_TEAM_PORT_SETTING_NAME))
i_slave_type = NM_SETTING_TEAM_SETTING_NAME;
else
continue;
if (slave_type) {
/* there are more then one matching port types, cannot detect the slave type. */
slave_type = NULL;
s_port = NULL;
break;
}
slave_type = i_slave_type;
s_port = s_iter;
}
if (out_s_port)
*out_s_port = s_port;
return slave_type;
}
/*************************************************************/
static void
destroy_gvalue (gpointer data)
{
@ -1288,6 +1370,34 @@ nm_setting_get_virtual_iface_name (NMSetting *setting)
return NULL;
}
NMSetting *
_nm_setting_find_in_list_required (GSList *all_settings,
const char *setting_name,
GError **error,
const char *error_prefix_setting_name,
const char *error_prefix_property_name)
{
NMSetting *setting;
g_return_val_if_fail (!error || !*error, NULL);
g_return_val_if_fail (all_settings, NULL);
g_return_val_if_fail (setting_name, NULL);
g_return_val_if_fail (!error_prefix_setting_name == !error_prefix_property_name, NULL);
setting = nm_setting_find_in_list (all_settings, setting_name);
if (!setting) {
g_set_error (error,
NM_CONNECTION_ERROR,
!strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME)
? NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND
: NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
_("Missing '%s' setting"),
setting_name);
if (error_prefix_setting_name)
g_prefix_error (error, "%s.%s: ", error_prefix_setting_name, error_prefix_property_name);
}
return setting;
}
NMSettingVerifyResult
_nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
@ -1303,6 +1413,22 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
NMSettingConnection *s_con;
const char *con_name;
if (!all_settings) {
/* nm_setting_verify() was called without passing on any other settings.
* Perform a relaxed verification, the setting might be valid when checked
* together with a NMSettingConnection as part of a NMConnection. */
if (interface_name && !nm_utils_iface_valid_name (interface_name)) {
/* Only if the interace name is invalid, there is an normalizable warning */
g_set_error_literal (error,
error_quark,
e_invalid_property,
_("property is invalid"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
return NM_SETTING_VERIFY_SUCCESS;
}
s_con = NM_SETTING_CONNECTION (nm_setting_find_in_list (all_settings, NM_SETTING_CONNECTION_SETTING_NAME));
con_name = s_con ? nm_setting_connection_get_interface_name (s_con) : NULL;
if (!interface_name && !con_name) {
@ -1333,7 +1459,7 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
return NM_SETTING_VERIFY_NORMALIZABLE;
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (!nm_utils_iface_valid_name (con_name)) {
/* NMSettingConnection:interface_name is invalid, we cannot normalize it. */
@ -1351,19 +1477,17 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
e_missing_property,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
return NM_SETTING_VERIFY_NORMALIZABLE;
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (strcmp (con_name, interface_name) != 0) {
/* con_name and interface_name are different. It can be normalized by setting interface_name
* to con_name. */
g_set_error_literal (error,
error_quark,
e_missing_property,
e_invalid_property,
_("property is invalid"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
/* we would like to make this a NORMALIZEABLE_ERROR, but that might
* break older connections. */
return NM_SETTING_VERIFY_NORMALIZABLE;
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
return NM_SETTING_VERIFY_SUCCESS;

View file

@ -108,7 +108,7 @@ typedef enum {
NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002,
NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 0x00000004
/* NOTE: if adding flags, update nm-setting-private.h as well */
/* NOTE: if adding flags, update nm-core-internal.h as well */
} NMSettingSecretFlags;
/**

View file

@ -34,30 +34,4 @@ gboolean _nm_utils_gvalue_array_validate (GValueArray *elements,
void _nm_value_transforms_register (void);
/***********************************************************/
typedef struct NMUtilsPrivateData {
const char * (*nm_setting_ip4_config_get_address_label) (NMSettingIP4Config *setting,
guint32 i);
gboolean (*nm_setting_ip4_config_add_address_with_label) (NMSettingIP4Config *setting,
NMIP4Address *address,
const char *label);
} NMUtilsPrivateData;
const NMUtilsPrivateData *nm_utils_get_private (void);
/**
* NM_UTILS_PRIVATE_CALL:
* @call: a call to a private libnm function
*
* Used to call private libnm functions. Eg, if there was a
* private function called nm_foo_get_bar(), you could call it like:
*
* bar = NM_UTILS_PRIVATE_CALL (nm_foo_get_bar (foo, x, y, z));
*
* This macro only exists inside the NetworkManager source tree and
* is not part of the public API.
*/
#define NM_UTILS_PRIVATE_CALL(call) (nm_utils_get_private ()->call)
#endif

View file

@ -536,6 +536,34 @@ done:
return valid;
}
/**
* _nm_utils_hash_values_to_slist:
* @hash: a #GHashTable
*
* Utility function to iterate over a hash table and return
* it's values as a #GSList.
*
* Returns: (element-type gpointer) (transfer container): a newly allocated #GSList
* containing the values of the hash table. The caller must free the
* returned list with g_slist_free(). The hash values are not owned
* by the returned list.
**/
GSList *
_nm_utils_hash_values_to_slist (GHashTable *hash)
{
GSList *list = NULL;
GHashTableIter iter;
void *value;
g_return_val_if_fail (hash, NULL);
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, NULL, &value))
list = g_slist_prepend (list, value);
return list;
}
static gboolean
device_supports_ap_ciphers (guint32 dev_caps,
guint32 ap_flags,
@ -2479,23 +2507,4 @@ nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_typ
}
}
/***********************************************************/
static const NMUtilsPrivateData data = {
.nm_setting_ip4_config_get_address_label = nm_setting_ip4_config_get_address_label,
.nm_setting_ip4_config_add_address_with_label = nm_setting_ip4_config_add_address_with_label,
};
/**
* nm_utils_get_private:
*
* Entry point for NetworkManager-internal API. You should not use this
* function for any reason.
*
* Returns: Who knows? It's a mystery.
*/
const NMUtilsPrivateData *
nm_utils_get_private (void)
{
return &data;
}

View file

@ -39,7 +39,7 @@
#include "nm-setting-vlan.h"
#include "nm-setting-bond.h"
#include "nm-utils.h"
#include "nm-utils-private.h"
#include "nm-core-internal.h"
#include "nm-dbus-glib-types.h"
#include "nm-test-utils.h"
@ -330,7 +330,7 @@ test_setting_ip4_config_labels (void)
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
g_assert_no_error (error);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 0);
g_assert_cmpstr (label, ==, NULL);
/* addr 2 */
@ -338,12 +338,12 @@ test_setting_ip4_config_labels (void)
nm_ip4_address_set_address (addr, 0x02020202);
nm_ip4_address_set_prefix (addr, 24);
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1"));
_nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1");
nm_ip4_address_unref (addr);
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
g_assert_no_error (error);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 1);
g_assert_cmpstr (label, ==, "eth0:1");
/* addr 3 */
@ -351,12 +351,12 @@ test_setting_ip4_config_labels (void)
nm_ip4_address_set_address (addr, 0x03030303);
nm_ip4_address_set_prefix (addr, 24);
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL));
_nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL);
nm_ip4_address_unref (addr);
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
g_assert_no_error (error);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 2));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 2);
g_assert_cmpstr (label, ==, NULL);
/* Remove addr 1 and re-verify remaining addresses */
@ -366,12 +366,12 @@ test_setting_ip4_config_labels (void)
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 0);
g_assert_cmpstr (label, ==, "eth0:1");
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 1);
g_assert_cmpstr (label, ==, NULL);
@ -395,12 +395,12 @@ test_setting_ip4_config_labels (void)
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 0);
g_assert_cmpstr (label, ==, NULL);
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 1);
g_assert_cmpstr (label, ==, NULL);
/* Setting labels now will leave addresses untouched */
@ -414,12 +414,12 @@ test_setting_ip4_config_labels (void)
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 0);
g_assert_cmpstr (label, ==, "eth0:1");
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
label = _nm_setting_ip4_config_get_address_label (s_ip4, 1);
g_assert_cmpstr (label, ==, NULL);
/* Setting labels to a value that's too short or too long will result in
@ -1837,11 +1837,29 @@ test_setting_compare_id (void)
g_assert (success);
}
static void
test_setting_compare_secrets (NMSettingSecretFlags secret_flags,
NMSettingCompareFlags comp_flags,
gboolean remove_secret)
typedef struct {
NMSettingSecretFlags secret_flags;
NMSettingCompareFlags comp_flags;
gboolean remove_secret;
} TestDataCompareSecrets;
static TestDataCompareSecrets *
test_data_compare_secrets_new (NMSettingSecretFlags secret_flags,
NMSettingCompareFlags comp_flags,
gboolean remove_secret)
{
TestDataCompareSecrets *data = g_new0 (TestDataCompareSecrets, 1);
data->secret_flags = secret_flags;
data->comp_flags = comp_flags;
data->remove_secret = remove_secret;
return data;
}
static void
test_setting_compare_secrets (gconstpointer test_data)
{
const TestDataCompareSecrets *data = test_data;
NMSetting *old, *new;
gboolean success;
@ -1854,26 +1872,25 @@ test_setting_compare_secrets (NMSettingSecretFlags secret_flags,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
NM_SETTING_WIRELESS_SECURITY_PSK, "really cool psk",
NULL);
nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, secret_flags, 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 (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);
}
success = nm_setting_compare (old, new, comp_flags);
success = nm_setting_compare (old, new, data->comp_flags);
g_assert (success);
}
static void
test_setting_compare_vpn_secrets (NMSettingSecretFlags secret_flags,
NMSettingCompareFlags comp_flags,
gboolean remove_secret)
test_setting_compare_vpn_secrets (gconstpointer test_data)
{
const TestDataCompareSecrets *data = test_data;
NMSetting *old, *new;
gboolean success;
@ -1886,11 +1903,11 @@ test_setting_compare_vpn_secrets (NMSettingSecretFlags secret_flags,
nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "asdfasdfasdf", "really adfasdfasdfasdf");
nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "0123456778", "abcdefghijklmnpqrstuvqxyz");
nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "borkbork", "yet another really secret password");
nm_setting_set_secret_flags (old, "borkbork", secret_flags, NULL);
nm_setting_set_secret_flags (old, "borkbork", data->secret_flags, NULL);
/* Clear "borkbork" from the duplicated setting */
new = nm_setting_duplicate (old);
if (remove_secret) {
if (data->remove_secret) {
nm_setting_vpn_remove_secret (NM_SETTING_VPN (new), "borkbork");
/* First make sure they are different */
@ -1898,7 +1915,7 @@ test_setting_compare_vpn_secrets (NMSettingSecretFlags secret_flags,
g_assert (success == FALSE);
}
success = nm_setting_compare (old, new, comp_flags);
success = nm_setting_compare (old, new, data->comp_flags);
g_assert (success);
}
@ -2545,43 +2562,27 @@ test_setting_old_uuid (void)
g_assert (success == TRUE);
}
/*
* nm_connection_verify() modifies the connection by setting
* the interface-name property to the virtual_iface_name of
* the type specific settings.
*
* It would be preferable of verify() not to touch the connection,
* but as it is now, stick with it and test it.
**/
static void
test_connection_verify_sets_interface_name (void)
test_connection_normalize_connection_interface_name (void)
{
NMConnection *con;
NMSettingConnection *s_con;
NMSettingBond *s_bond;
GError *error = NULL;
gboolean success;
s_con = (NMSettingConnection *) nm_setting_connection_new ();
g_object_set (G_OBJECT (s_con),
NM_SETTING_CONNECTION_ID, "test1",
NM_SETTING_CONNECTION_UUID, "22001632-bbb4-4616-b277-363dce3dfb5b",
NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME,
NULL);
s_bond = (NMSettingBond *) nm_setting_bond_new ();
con = nmtst_create_minimal_connection ("test1",
"22001632-bbb4-4616-b277-363dce3dfb5b",
NM_SETTING_BOND_SETTING_NAME,
&s_con);
s_bond = nm_connection_get_setting_bond (con);
g_object_set (G_OBJECT (s_bond),
NM_SETTING_BOND_INTERFACE_NAME, "bond-x",
NULL);
con = nm_simple_connection_new ();
nm_connection_add_setting (con, NM_SETTING (s_con));
nm_connection_add_setting (con, NM_SETTING (s_bond));
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, NULL);
/* for backward compatiblity, normalizes the interface name */
success = nm_connection_verify (con, &error);
g_assert (success && !error);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, "bond-x");
@ -2594,151 +2595,575 @@ test_connection_verify_sets_interface_name (void)
static void
test_connection_normalize_virtual_iface_name (void)
{
NMConnection *con;
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
NMSettingVlan *s_vlan;
NMSetting *setting;
GError *error = NULL;
gboolean success;
const char *IFACE_NAME = "iface";
const char *IFACE_VIRT = "iface-X";
gboolean modified = FALSE;
con = nm_simple_connection_new ();
con = nmtst_create_minimal_connection ("test1",
"22001632-bbb4-4616-b277-363dce3dfb5b",
NM_SETTING_VLAN_SETTING_NAME,
&s_con);
setting = nm_setting_ip4_config_new ();
g_object_set (setting,
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NULL);
nm_connection_add_setting (con, setting);
nm_connection_add_setting (con,
g_object_new (NM_TYPE_SETTING_IP4_CONFIG,
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NULL));
setting = nm_setting_ip6_config_new ();
g_object_set (setting,
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
NULL);
nm_connection_add_setting (con, setting);
nm_connection_add_setting (con,
g_object_new (NM_TYPE_SETTING_IP6_CONFIG,
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NULL));
s_vlan = nm_connection_get_setting_vlan (con);
s_con = (NMSettingConnection *) nm_setting_connection_new ();
g_object_set (G_OBJECT (s_con),
NM_SETTING_CONNECTION_ID, "test1",
NM_SETTING_CONNECTION_UUID, "22001632-bbb4-4616-b277-363dce3dfb5b",
NM_SETTING_CONNECTION_TYPE, NM_SETTING_VLAN_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME,
NULL);
s_vlan = (NMSettingVlan *) nm_setting_vlan_new ();
g_object_set (G_OBJECT (s_vlan),
NM_SETTING_VLAN_INTERFACE_NAME, IFACE_VIRT,
NM_SETTING_VLAN_PARENT, "eth0",
NULL);
nm_connection_add_setting (con, NM_SETTING (s_con));
nm_connection_add_setting (con, NM_SETTING (s_vlan));
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, NULL);
g_object_set (G_OBJECT (s_vlan), NM_SETTING_VLAN_INTERFACE_NAME, IFACE_VIRT, NULL);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_VIRT);
/* for backward compatiblity, normalizes the interface name */
success = nm_connection_verify (con, &error);
g_assert (success && !error);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_VIRT);
success = nm_connection_normalize (con, NULL, &modified, &error);
g_assert (success && !error);
g_assert (modified);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_VLAN_ERROR, NM_SETTING_VLAN_ERROR_INVALID_PROPERTY);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_NAME);
success = nm_connection_verify (con, &error);
g_assert (success && !error);
g_object_unref (con);
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, NULL);
g_object_set (G_OBJECT (s_vlan), NM_SETTING_VLAN_INTERFACE_NAME, NULL, NULL);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_VLAN_ERROR, NM_SETTING_VLAN_ERROR_MISSING_PROPERTY);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_NAME);
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, NULL, NULL);
g_object_set (G_OBJECT (s_vlan), NM_SETTING_VLAN_INTERFACE_NAME, IFACE_NAME, NULL);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, NULL);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_NAME);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_NAME);
}
static void
_test_connection_normalize_type_normalizable_setting (const char *type,
void (*prepare_normalizable_fcn) (NMConnection *con))
{
NMSettingConnection *s_con;
NMSetting *s_base;
GType base_type;
gs_unref_object NMConnection *con = NULL;
gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type);
base_type = nm_setting_lookup_type (type);
g_assert (base_type != G_TYPE_INVALID);
g_assert (_nm_setting_type_is_base_type (base_type));
con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL);
if (prepare_normalizable_fcn)
prepare_normalizable_fcn (con);
g_assert (!nm_connection_get_setting_by_name (con, type));
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND);
s_base = nm_connection_get_setting_by_name (con, type);
g_assert (s_base);
g_assert (G_OBJECT_TYPE (s_base) == base_type);
}
static void
_test_connection_normalize_type_unnormalizable_setting (const char *type)
{
NMSettingConnection *s_con;
GType base_type;
gs_unref_object NMConnection *con = NULL;
gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type);
base_type = nm_setting_lookup_type (type);
g_assert (base_type != G_TYPE_INVALID);
g_assert (_nm_setting_type_is_base_type (base_type));
con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND);
}
static void
_test_connection_normalize_type_normalizable_type (const char *type,
NMSetting *(*add_setting_fcn) (NMConnection *con))
{
NMSettingConnection *s_con;
NMSetting *s_base;
GType base_type;
gs_unref_object NMConnection *con = NULL;
gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type);
base_type = nm_setting_lookup_type (type);
g_assert (base_type != G_TYPE_INVALID);
g_assert (_nm_setting_type_is_base_type (base_type));
con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
if (add_setting_fcn)
s_base = add_setting_fcn (con);
else {
s_base = NM_SETTING (g_object_new (base_type, NULL));
nm_connection_add_setting (con, s_base);
}
g_assert (!nm_connection_get_connection_type (con));
g_assert (nm_connection_get_setting_by_name (con, type) == s_base);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_assert_cmpstr (nm_connection_get_connection_type (con), ==, type);
g_assert (nm_connection_get_setting_by_name (con, type) == s_base);
}
static NMSetting *
_add_setting_fcn_adsl (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_ADSL,
NM_SETTING_ADSL_USERNAME, "test-user",
NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOA,
NM_SETTING_ADSL_ENCAPSULATION, NM_SETTING_ADSL_ENCAPSULATION_VCMUX,
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_bluetooth (NMConnection *con)
{
NMSetting *setting;
GByteArray *bdaddr = nm_utils_hwaddr_atoba ("11:22:33:44:55:66", ETH_ALEN);
setting = g_object_new (NM_TYPE_SETTING_BLUETOOTH,
NM_SETTING_BLUETOOTH_BDADDR, bdaddr,
NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
NULL);
g_byte_array_free (bdaddr, TRUE);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_bond (NMConnection *con)
{
NMSetting *setting;
NMSettingConnection *s_con;
setting = g_object_new (NM_TYPE_SETTING_BOND, NULL);
nm_connection_add_setting (con, setting);
s_con = nm_connection_get_setting_connection (con);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bond",
NULL);
return setting;
}
static NMSetting *
_add_setting_fcn_bridge (NMConnection *con)
{
NMSetting *setting;
NMSettingConnection *s_con;
setting = g_object_new (NM_TYPE_SETTING_BRIDGE, NULL);
nm_connection_add_setting (con, setting);
s_con = nm_connection_get_setting_connection (con);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bridge",
NULL);
return setting;
}
static NMSetting *
_add_setting_fcn_cdma (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_CDMA,
NM_SETTING_CDMA_NUMBER, "test-number",
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_infiniband (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_INFINIBAND,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected",
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_olpc_mesh (NMConnection *con)
{
NMSetting *setting;
const char *ssid_data = "ssid-test";
GByteArray *ssid = g_byte_array_new ();
g_byte_array_append (ssid, (const guint8 *) ssid_data, strlen (ssid_data));
setting = g_object_new (NM_TYPE_SETTING_OLPC_MESH,
NM_SETTING_OLPC_MESH_SSID, ssid,
NM_SETTING_OLPC_MESH_CHANNEL, 1,
NULL);
g_byte_array_free (ssid, TRUE);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_team (NMConnection *con)
{
NMSetting *setting;
NMSettingConnection *s_con;
setting = g_object_new (NM_TYPE_SETTING_TEAM, NULL);
nm_connection_add_setting (con, setting);
s_con = nm_connection_get_setting_connection (con);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "test-team",
NULL);
return setting;
}
static NMSetting *
_add_setting_fcn_vlan (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_VLAN,
NM_SETTING_VLAN_PARENT, "test-parent",
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_vpn (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_VPN,
NM_SETTING_VPN_SERVICE_TYPE, "test-vpn-service-type",
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_wimax (NMConnection *con)
{
NMSetting *setting;
setting = g_object_new (NM_TYPE_SETTING_WIMAX,
NM_SETTING_WIMAX_NETWORK_NAME, "test-network",
NULL);
nm_connection_add_setting (con, setting);
return setting;
}
static NMSetting *
_add_setting_fcn_wireless (NMConnection *con)
{
NMSetting *setting;
const char *ssid_data = "ssid-test";
GByteArray *ssid = g_byte_array_new ();
g_byte_array_append (ssid, (const guint8 *) ssid_data, strlen (ssid_data));
setting = g_object_new (NM_TYPE_SETTING_WIRELESS,
NM_SETTING_WIRELESS_SSID, ssid,
NULL);
g_byte_array_free (ssid, TRUE);
nm_connection_add_setting (con, setting);
return setting;
}
static void
_prepare_normalizable_fcn_vlan (NMConnection *con)
{
GByteArray *mac_addr = nm_utils_hwaddr_atoba ("11:22:33:44:55:66", ETH_ALEN);
nm_connection_add_setting (con, g_object_new (NM_TYPE_SETTING_WIRED,
NM_SETTING_WIRED_MAC_ADDRESS, mac_addr,
NULL));
g_byte_array_free (mac_addr, TRUE);
}
static void
test_connection_normalize_type (void)
{
guint i;
struct {
const char *type;
gboolean normalizable;
NMSetting *(*add_setting_fcn) (NMConnection *con);
void (*prepare_normalizable_fcn) (NMConnection *con);
} types[] = {
{ NM_SETTING_GENERIC_SETTING_NAME, TRUE },
{ NM_SETTING_GSM_SETTING_NAME, TRUE },
{ NM_SETTING_WIRED_SETTING_NAME, TRUE },
{ NM_SETTING_VLAN_SETTING_NAME, TRUE, _add_setting_fcn_vlan, _prepare_normalizable_fcn_vlan },
{ NM_SETTING_ADSL_SETTING_NAME, FALSE, _add_setting_fcn_adsl },
{ NM_SETTING_BLUETOOTH_SETTING_NAME, FALSE, _add_setting_fcn_bluetooth },
{ NM_SETTING_BOND_SETTING_NAME, FALSE, _add_setting_fcn_bond },
{ NM_SETTING_BRIDGE_SETTING_NAME, FALSE, _add_setting_fcn_bridge },
{ NM_SETTING_CDMA_SETTING_NAME, FALSE, _add_setting_fcn_cdma },
{ NM_SETTING_INFINIBAND_SETTING_NAME, FALSE, _add_setting_fcn_infiniband },
{ NM_SETTING_OLPC_MESH_SETTING_NAME, FALSE, _add_setting_fcn_olpc_mesh },
{ NM_SETTING_TEAM_SETTING_NAME, FALSE, _add_setting_fcn_team },
{ NM_SETTING_VLAN_SETTING_NAME, FALSE, _add_setting_fcn_vlan },
{ NM_SETTING_VPN_SETTING_NAME, FALSE, _add_setting_fcn_vpn },
{ NM_SETTING_WIMAX_SETTING_NAME, FALSE, _add_setting_fcn_wimax },
{ NM_SETTING_WIRELESS_SETTING_NAME, FALSE, _add_setting_fcn_wireless },
{ 0 },
};
for (i = 0; types[i].type; i++) {
const char *type = types[i].type;
if (types[i].normalizable)
_test_connection_normalize_type_normalizable_setting (type, types[i].prepare_normalizable_fcn);
else
_test_connection_normalize_type_unnormalizable_setting (type);
_test_connection_normalize_type_normalizable_type (type, types[i].add_setting_fcn);
}
}
static void
test_connection_normalize_slave_type_1 (void)
{
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_1",
"cc4cd5df-45dc-483e-b291-6b76c2338ecb",
NM_SETTING_WIRED_SETTING_NAME, &s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
g_object_set (s_con,
NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge",
NULL);
g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_SLAVE_SETTING_NOT_FOUND);
g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME);
}
static void
test_connection_normalize_slave_type_2 (void)
{
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_2",
"40bea008-ca72-439a-946b-e65f827656f9",
NM_SETTING_WIRED_SETTING_NAME, &s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
g_object_set (s_con,
NM_SETTING_CONNECTION_SLAVE_TYPE, NULL,
NULL);
nm_connection_add_setting (con, nm_setting_bridge_port_new ());
g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME);
}
static void
test_connection_normalize_infiniband_mtu (void)
{
gs_unref_object NMConnection *con = NULL;
NMSettingInfiniband *s_infini;
con = nmtst_create_minimal_connection ("test_connection_normalize_infiniband_mtu", NULL,
NM_SETTING_INFINIBAND_SETTING_NAME, NULL);
s_infini = nm_connection_get_setting_infiniband (con);
g_object_set (s_infini,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected",
NULL);
nmtst_assert_connection_verifies_and_normalizable (con);
g_object_set (s_infini,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram",
NM_SETTING_INFINIBAND_MTU, (guint) 2044,
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini));
g_object_set (s_infini,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram",
NM_SETTING_INFINIBAND_MTU, (guint) 2045,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_INFINIBAND_ERROR, NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY);
g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini));
g_object_set (s_infini,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected",
NM_SETTING_INFINIBAND_MTU, (guint) 65520,
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini));
g_object_set (s_infini,
NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected",
NM_SETTING_INFINIBAND_MTU, (guint) 65521,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_SETTING_INFINIBAND_ERROR, NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY);
g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini));
}
NMTST_DEFINE ();
int main (int argc, char **argv)
{
char *base;
nmtst_init (&argc, &argv, TRUE);
/* The tests */
test_setting_vpn_items ();
test_setting_vpn_update_secrets ();
test_setting_vpn_modify_during_foreach ();
test_setting_ip4_config_labels ();
test_setting_ip6_config_old_address_array ();
test_setting_gsm_apn_spaces ();
test_setting_gsm_apn_bad_chars ();
test_setting_gsm_apn_underscore ();
test_setting_gsm_without_number ();
test_setting_to_hash_all ();
test_setting_to_hash_no_secrets ();
test_setting_to_hash_only_secrets ();
test_setting_compare_id ();
test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
test_setting_old_uuid ();
g_test_add_func ("/core/general/test_setting_vpn_items", test_setting_vpn_items);
g_test_add_func ("/core/general/test_setting_vpn_update_secrets", test_setting_vpn_update_secrets);
g_test_add_func ("/core/general/test_setting_vpn_modify_during_foreach", test_setting_vpn_modify_during_foreach);
g_test_add_func ("/core/general/test_setting_ip4_config_labels", test_setting_ip4_config_labels);
g_test_add_func ("/core/general/test_setting_ip6_config_old_address_array", test_setting_ip6_config_old_address_array);
g_test_add_func ("/core/general/test_setting_gsm_apn_spaces", test_setting_gsm_apn_spaces);
g_test_add_func ("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars);
g_test_add_func ("/core/general/test_setting_gsm_apn_underscore", test_setting_gsm_apn_underscore);
g_test_add_func ("/core/general/test_setting_gsm_without_number", test_setting_gsm_without_number);
g_test_add_func ("/core/general/test_setting_to_hash_all", test_setting_to_hash_all);
g_test_add_func ("/core/general/test_setting_to_hash_no_secrets", test_setting_to_hash_no_secrets);
g_test_add_func ("/core/general/test_setting_to_hash_only_secrets", test_setting_to_hash_only_secrets);
g_test_add_func ("/core/general/test_setting_compare_id", test_setting_compare_id);
#define ADD_FUNC(func, secret_flags, comp_flags, remove_secret) \
g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func), \
test_data_compare_secrets_new (secret_flags, comp_flags, remove_secret), \
func, g_free)
ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
g_test_add_func ("/core/general/test_setting_old_uuid", test_setting_old_uuid);
test_connection_to_hash_setting_name ();
test_setting_new_from_hash ();
test_connection_replace_settings ();
test_connection_replace_settings_from_connection ();
test_connection_new_from_hash ();
test_connection_verify_sets_interface_name ();
test_connection_normalize_virtual_iface_name ();
g_test_add_func ("/core/general/test_connection_to_hash_setting_name", test_connection_to_hash_setting_name);
g_test_add_func ("/core/general/test_setting_new_from_hash", test_setting_new_from_hash);
g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings);
g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection);
g_test_add_func ("/core/general/test_connection_new_from_hash", test_connection_new_from_hash);
g_test_add_func ("/core/general/test_connection_normalize_connection_interface_name", test_connection_normalize_connection_interface_name);
g_test_add_func ("/core/general/test_connection_normalize_virtual_iface_name", test_connection_normalize_virtual_iface_name);
g_test_add_func ("/core/general/test_connection_normalize_type", test_connection_normalize_type);
g_test_add_func ("/core/general/test_connection_normalize_slave_type_1", test_connection_normalize_slave_type_1);
g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2);
g_test_add_func ("/core/general/test_connection_normalize_infiniband_mtu", test_connection_normalize_infiniband_mtu);
test_setting_connection_permissions_helpers ();
test_setting_connection_permissions_property ();
g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers);
g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property);
test_connection_compare_same ();
test_connection_compare_key_only_in_a ();
test_connection_compare_setting_only_in_a ();
test_connection_compare_key_only_in_b ();
test_connection_compare_setting_only_in_b ();
g_test_add_func ("/core/general/test_connection_compare_same", test_connection_compare_same);
g_test_add_func ("/core/general/test_connection_compare_key_only_in_a", test_connection_compare_key_only_in_a);
g_test_add_func ("/core/general/test_connection_compare_setting_only_in_a", test_connection_compare_setting_only_in_a);
g_test_add_func ("/core/general/test_connection_compare_key_only_in_b", test_connection_compare_key_only_in_b);
g_test_add_func ("/core/general/test_connection_compare_setting_only_in_b", test_connection_compare_setting_only_in_b);
test_connection_diff_a_only ();
test_connection_diff_same ();
test_connection_diff_different ();
test_connection_diff_no_secrets ();
test_connection_diff_inferrable ();
test_connection_good_base_types ();
test_connection_bad_base_types ();
g_test_add_func ("/core/general/test_connection_diff_a_only", test_connection_diff_a_only);
g_test_add_func ("/core/general/test_connection_diff_same", test_connection_diff_same);
g_test_add_func ("/core/general/test_connection_diff_different", test_connection_diff_different);
g_test_add_func ("/core/general/test_connection_diff_no_secrets", test_connection_diff_no_secrets);
g_test_add_func ("/core/general/test_connection_diff_inferrable", test_connection_diff_inferrable);
g_test_add_func ("/core/general/test_connection_good_base_types", test_connection_good_base_types);
g_test_add_func ("/core/general/test_connection_bad_base_types", test_connection_bad_base_types);
test_hwaddr_aton_ether_normal ();
test_hwaddr_aton_ib_normal ();
test_hwaddr_aton_no_leading_zeros ();
test_hwaddr_aton_malformed ();
test_hwaddr_equal ();
g_test_add_func ("/core/general/test_hwaddr_aton_ether_normal", test_hwaddr_aton_ether_normal);
g_test_add_func ("/core/general/test_hwaddr_aton_ib_normal", test_hwaddr_aton_ib_normal);
g_test_add_func ("/core/general/test_hwaddr_aton_no_leading_zeros", test_hwaddr_aton_no_leading_zeros);
g_test_add_func ("/core/general/test_hwaddr_aton_malformed", test_hwaddr_aton_malformed);
g_test_add_func ("/core/general/test_hwaddr_equal", test_hwaddr_equal);
test_ip4_prefix_to_netmask ();
test_ip4_netmask_to_prefix ();
g_test_add_func ("/core/general/test_ip4_prefix_to_netmask", test_ip4_prefix_to_netmask);
g_test_add_func ("/core/general/test_ip4_netmask_to_prefix", test_ip4_netmask_to_prefix);
test_connection_changed_signal ();
test_setting_connection_changed_signal ();
test_setting_bond_changed_signal ();
test_setting_ip4_changed_signal ();
test_setting_ip6_changed_signal ();
test_setting_vlan_changed_signal ();
test_setting_vpn_changed_signal ();
test_setting_wired_changed_signal ();
test_setting_wireless_changed_signal ();
test_setting_wireless_security_changed_signal ();
test_setting_802_1x_changed_signal ();
g_test_add_func ("/core/general/test_connection_changed_signal", test_connection_changed_signal);
g_test_add_func ("/core/general/test_setting_connection_changed_signal", test_setting_connection_changed_signal);
g_test_add_func ("/core/general/test_setting_bond_changed_signal", test_setting_bond_changed_signal);
g_test_add_func ("/core/general/test_setting_ip4_changed_signal", test_setting_ip4_changed_signal);
g_test_add_func ("/core/general/test_setting_ip6_changed_signal", test_setting_ip6_changed_signal);
g_test_add_func ("/core/general/test_setting_vlan_changed_signal", test_setting_vlan_changed_signal);
g_test_add_func ("/core/general/test_setting_vpn_changed_signal", test_setting_vpn_changed_signal);
g_test_add_func ("/core/general/test_setting_wired_changed_signal", test_setting_wired_changed_signal);
g_test_add_func ("/core/general/test_setting_wireless_changed_signal", test_setting_wireless_changed_signal);
g_test_add_func ("/core/general/test_setting_wireless_security_changed_signal", test_setting_wireless_security_changed_signal);
g_test_add_func ("/core/general/test_setting_802_1x_changed_signal", test_setting_802_1x_changed_signal);
base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base);
g_free (base);
return 0;
return g_test_run ();
}

View file

@ -185,12 +185,23 @@ setting_changed_cb (NMSetting *setting,
g_signal_emit (self, signals[CHANGED], 0);
}
static gboolean
_setting_release (gpointer key, gpointer value, gpointer user_data)
{
g_signal_handlers_disconnect_by_func (user_data, setting_changed_cb, value);
return TRUE;
}
static void
_nm_connection_add_setting (NMConnection *connection, NMSetting *setting)
{
g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings,
(gpointer) G_OBJECT_TYPE_NAME (setting),
setting);
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
const char *name = G_OBJECT_TYPE_NAME (setting);
NMSetting *s_old;
if ((s_old = g_hash_table_lookup (priv->settings, (gpointer) name)))
g_signal_handlers_disconnect_by_func (s_old, setting_changed_cb, connection);
g_hash_table_insert (priv->settings, (gpointer) name, setting);
/* Listen for property changes so we can emit the 'changed' signal */
g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection);
}
@ -347,7 +358,7 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error)
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
if ((changed = g_hash_table_size (priv->settings) > 0))
g_hash_table_remove_all (priv->settings);
g_hash_table_foreach_remove (priv->settings, _setting_release, connection);
g_hash_table_iter_init (&iter, new);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
@ -435,7 +446,7 @@ nm_connection_replace_settings_from_connection (NMConnection *connection,
priv = NM_CONNECTION_GET_PRIVATE (connection);
if ((changed = g_hash_table_size (priv->settings) > 0))
g_hash_table_remove_all (priv->settings);
g_hash_table_foreach_remove (priv->settings, _setting_release, connection);
if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (new_connection)->settings)) {
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (new_connection)->settings);
@ -1494,7 +1505,7 @@ nm_connection_duplicate (NMConnection *connection)
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
nm_connection_add_setting (dup, nm_setting_duplicate (setting));
_nm_connection_add_setting (dup, nm_setting_duplicate (setting));
return dup;
}
@ -2048,14 +2059,8 @@ dispose (GObject *object)
{
NMConnection *self = NM_CONNECTION (object);
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (self);
GHashTableIter iter;
NMSetting *setting;
g_hash_table_iter_init (&iter, priv->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
g_signal_handlers_disconnect_by_func (setting, setting_changed_cb, self);
g_hash_table_iter_remove (&iter);
}
g_hash_table_foreach_remove (priv->settings, _setting_release, self);
G_OBJECT_CLASS (nm_connection_parent_class)->dispose (object);
}
@ -2066,6 +2071,7 @@ finalize (GObject *object)
NMConnection *connection = NM_CONNECTION (object);
NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
g_assert (g_hash_table_size (priv->settings) == 0);
g_hash_table_destroy (priv->settings);
g_free (priv->path);

View file

@ -206,6 +206,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
/* FIXME: verify() should not modify the setting, but return NORMALIZABLE success. */
if (!g_strcmp0 (priv->transport_mode, "datagram")) {
if (priv->mtu > 2044)
priv->mtu = 2044;

View file

@ -1340,7 +1340,7 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
* to con_name. */
g_set_error_literal (error,
error_quark,
e_missing_property,
e_invalid_property,
_("property is invalid"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
/* we would like to make this a NORMALIZEABLE_ERROR, but that might

View file

@ -878,7 +878,6 @@ global:
nm_utils_deinit;
nm_utils_escape_ssid;
nm_utils_file_is_pkcs12;
nm_utils_get_private;
nm_utils_gvalue_hash_dup;
nm_utils_hex2byte;
nm_utils_hexstr2bin;

View file

@ -25,7 +25,7 @@
#include "nm-vpn-plugin-utils.h"
#include "nm-vpn-plugin.h"
#include "nm-setting-private.h"
#include "nm-core-internal.h"
#include "nm-dbus-glib-types.h"
#define DATA_KEY_TAG "DATA_KEY="

View file

@ -59,6 +59,7 @@ libnm-core/nm-setting-ip6-config.c
libnm-core/nm-setting-olpc-mesh.c
libnm-core/nm-setting-ppp.c
libnm-core/nm-setting-pppoe.c
libnm-core/nm-setting-team-port.c
libnm-core/nm-setting-vlan.c
libnm-core/nm-setting-vpn.c
libnm-core/nm-setting-wimax.c

View file

@ -33,7 +33,7 @@
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-setting-private.h"
#include "nm-core-internal.h"
#include "nm-logging.h"
#include "nm-device.h"
#include "nm-setting-connection.h"

View file

@ -29,7 +29,7 @@
#include "nm-dbus-glib-types.h"
#include "nm-ip4-config-glue.h"
#include "NetworkManagerUtils.h"
#include "nm-utils-private.h"
#include "nm-core-internal.h"
G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT)
@ -328,7 +328,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, i
/* Addresses */
for (i = 0; i < naddresses; i++) {
NMIP4Address *s_addr = nm_setting_ip4_config_get_address (setting, i);
const char *label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (setting, i));
const char *label = _nm_setting_ip4_config_get_address_label (setting, i);
NMPlatformIP4Address address;
memset (&address, 0, sizeof (address));
@ -426,7 +426,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
nm_ip4_address_set_gateway (s_addr, gateway);
if (*address->label)
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, s_addr, address->label));
_nm_setting_ip4_config_add_address_with_label (s_ip4, s_addr, address->label);
else
nm_setting_ip4_config_add_address (s_ip4, s_addr);
nm_ip4_address_unref (s_addr);

View file

@ -29,6 +29,7 @@
#include <nm-setting-vpn.h>
#include <nm-setting-wireless.h>
#include <nm-utils.h>
#include "nm-core-internal.h"
#include "nm-settings-connection.h"
#include "nm-session-monitor.h"
@ -1162,7 +1163,7 @@ get_settings_auth_cb (NMSettingsConnection *self,
s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (dupl_con));
if (bssid_list && s_wifi)
g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssid_list, NULL);
g_slist_free_full (bssid_list, g_free);
g_slist_free (bssid_list);
/* 802-11-wireless.security property is deprecated. But we set it here so that
* we don't disturb old clients that might expect it being properly set for
@ -1745,24 +1746,15 @@ mac_dup (const guint8 *old)
*
* Returns current list of seen BSSIDs for the connection.
*
* Returns: (transfer full) list of seen BSSIDs (in the standard hex-digits-and-colons notation).
* The caller is responsible for freeing the list.
* Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation).
* The caller is responsible for freeing the list, but not the content.
**/
GSList *
nm_settings_connection_get_seen_bssids (NMSettingsConnection *connection)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
GHashTableIter iter;
char *bssid_str;
GSList *bssid_list = NULL;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL);
g_hash_table_iter_init (&iter, priv->seen_bssids);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &bssid_str))
bssid_list = g_slist_prepend (bssid_list, g_strdup (bssid_str));
return bssid_list;
return _nm_utils_hash_values_to_slist (NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->seen_bssids);
}
/**

View file

@ -52,6 +52,7 @@
#include <nm-setting-wireless-security.h>
#include <nm-setting-bond.h>
#include <nm-utils.h>
#include "nm-core-internal.h"
#include "nm-device-ethernet.h"
#include "nm-dbus-glib-types.h"
@ -1763,13 +1764,8 @@ get_connections (NMConnectionProvider *provider)
GSList *list = NULL;
NMSettings *self = NM_SETTINGS (provider);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GHashTableIter iter;
NMSettingsConnection *connection;
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection))
list = g_slist_prepend (list, connection);
list = g_slist_reverse (list);
list = _nm_utils_hash_values_to_slist (priv->connections);
/* Cache the list every call so we can keep it 'const' for callers */
g_slist_free (priv->get_connections_cache);

View file

@ -48,7 +48,7 @@
#include <nm-setting-bridge-port.h>
#include <nm-setting-dcb.h>
#include <nm-setting-generic.h>
#include <nm-utils-private.h>
#include "nm-core-internal.h"
#include <nm-utils.h>
#include "nm-platform.h"
@ -1574,7 +1574,7 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo
ok = read_full_ip4_address (parsed, network_file, -1, addr, &err);
svCloseFile (parsed);
if (ok) {
if (!NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device)))
if (!_nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device))
PARSE_WARNING ("duplicate IP4 address in alias file %s", item);
} else {
PARSE_WARNING ("error reading IP4 address from alias file '%s': %s",
@ -3802,11 +3802,6 @@ wireless_connection_from_ifcfg (const char *file,
}
nm_connection_add_setting (connection, con_setting);
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4020,11 +4015,6 @@ wired_connection_from_ifcfg (const char *file,
if (s_8021x)
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4183,11 +4173,6 @@ infiniband_connection_from_ifcfg (const char *file,
}
nm_connection_add_setting (connection, infiniband_setting);
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4308,11 +4293,6 @@ bond_connection_from_ifcfg (const char *file,
if (s_8021x)
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4419,11 +4399,6 @@ team_connection_from_ifcfg (const char *file,
if (s_8021x)
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4604,11 +4579,6 @@ bridge_connection_from_ifcfg (const char *file,
}
nm_connection_add_setting (connection, bridge_setting);
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}
@ -4921,10 +4891,6 @@ vlan_connection_from_ifcfg (const char *file,
if (s_8021x)
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
if (!nm_connection_verify (connection, error)) {
g_object_unref (connection);
return NULL;
}
return connection;
}

View file

@ -44,7 +44,7 @@
#include <nm-setting-serial.h>
#include <nm-setting-vlan.h>
#include <nm-setting-dcb.h>
#include <nm-utils-private.h>
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
@ -2986,7 +2986,7 @@ test_read_wired_aliases_good (void)
TEST_IFCFG_ALIASES_GOOD,
i);
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), expected_label[j]) == 0,
ASSERT (g_strcmp0 (_nm_setting_ip4_config_get_address_label (s_ip4, i), expected_label[j]) == 0,
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
TEST_IFCFG_ALIASES_GOOD,
i);
@ -3113,7 +3113,7 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id)
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address gateway",
base);
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)), expected_label) == 0,
ASSERT (g_strcmp0 (_nm_setting_ip4_config_get_address_label (s_ip4, 0), expected_label) == 0,
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address label",
base);
@ -8185,7 +8185,7 @@ test_write_wired_aliases (void)
nm_ip4_address_set_address (addr, ip[i]);
nm_ip4_address_set_prefix (addr, prefix);
nm_ip4_address_set_gateway (addr, gw);
NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i]));
_nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i]);
nm_ip4_address_unref (addr);
}
@ -8293,7 +8293,7 @@ test_write_wired_aliases (void)
testfile,
i);
ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), label[j]) == 0,
ASSERT (g_strcmp0 (_nm_setting_ip4_config_get_address_label (s_ip4, i), label[j]) == 0,
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
testfile,
i);
@ -12346,8 +12346,7 @@ test_write_bridge_main (void)
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
NULL);
g_assert (nm_connection_verify (connection, &error));
g_assert_no_error (error);
nmtst_assert_connection_verifies_after_normalization (connection, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
/* Save the ifcfg */
success = writer_new_connection (connection,
@ -13131,9 +13130,7 @@ test_write_bond_main (void)
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
NULL);
ASSERT (nm_connection_verify (connection, &error) == TRUE,
"bond-main-write", "failed to verify connection: %s",
(error && error->message) ? error->message : "(unknown)");
nmtst_assert_connection_verifies_after_normalization (connection, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
/* Save the ifcfg */
success = writer_new_connection (connection,
@ -14216,9 +14213,7 @@ test_write_team_master (void)
s_wired = (NMSettingWired *) nm_setting_wired_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wired));
success = nm_connection_verify (connection, &error);
g_assert_no_error (error);
g_assert (success);
nmtst_assert_connection_verifies_after_normalization (connection, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY);
/* Save the ifcfg */
success = writer_new_connection (connection,
@ -14409,8 +14404,11 @@ test_read_team_port_empty_config (void)
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "team0");
/* Empty TEAM_PORT_CONFIG means no team-port setting */
g_assert (nm_connection_get_setting_team_port (connection) == NULL);
/* Normalization adds a team-port setting */
g_assert (nm_connection_get_setting_team_port (connection));
/* empty/missing config */
g_assert (!nm_setting_team_port_get_config (nm_connection_get_setting_team_port (connection)));
g_object_unref (connection);
}

View file

@ -38,7 +38,7 @@
#include <nm-setting-vlan.h>
#include <nm-setting-team.h>
#include <nm-setting-team-port.h>
#include <nm-utils-private.h>
#include "nm-core-internal.h"
#include <nm-utils.h>
#include "nm-logging.h"
@ -1927,7 +1927,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
NMIP4Address *addr;
guint32 ip;
if (i > 0 && NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)))
if (i > 0 && _nm_setting_ip4_config_get_address_label (s_ip4, i))
continue;
if (n == 0) {
@ -2202,7 +2202,7 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
guint32 ip;
shvarFile *ifcfg;
label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i));
label = _nm_setting_ip4_config_get_address_label (s_ip4, i);
if (!label)
continue;
if ( strncmp (label, base_name, base_name_len) != 0

View file

@ -41,6 +41,7 @@
#include "nm-setting-wired.h"
#include "nm-setting-ppp.h"
#include "nm-utils.h"
#include "nm-core-internal.h"
#include "nm-ifupdown-connection.h"
#include "plugin.h"
@ -505,9 +506,7 @@ static GSList*
SCPluginIfupdown_get_connections (NMSystemConfigInterface *config)
{
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
GSList *connections = NULL;
GHashTableIter iter;
gpointer value;
GSList *connections;
nm_log_info (LOGD_SETTINGS, "(%d) ... get_connections.", GPOINTER_TO_UINT(config));
@ -516,9 +515,7 @@ SCPluginIfupdown_get_connections (NMSystemConfigInterface *config)
return NULL;
}
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &value))
connections = g_slist_prepend (connections, value);
connections = _nm_utils_hash_values_to_slist (priv->connections);
nm_log_info (LOGD_SETTINGS, "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections));
return connections;

View file

@ -36,6 +36,7 @@
#include <nm-utils.h>
#include <nm-config.h>
#include <nm-logging.h>
#include "nm-core-internal.h"
#include "plugin.h"
#include "nm-system-config-interface.h"
@ -372,20 +373,13 @@ static GSList *
get_connections (NMSystemConfigInterface *config)
{
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
GHashTableIter iter;
gpointer data = NULL;
GSList *list = NULL;
if (!priv->initialized) {
setup_monitoring (config);
read_connections (config);
priv->initialized = TRUE;
}
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &data))
list = g_slist_prepend (list, data);
return list;
return _nm_utils_hash_values_to_slist (priv->connections);
}
static gboolean

View file

@ -1200,30 +1200,6 @@ read_vpn_secrets (GKeyFile *file, NMSettingVpn *s_vpn)
g_strfreev (keys);
}
static void
ensure_slave_setting (NMConnection *connection)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
const char *slave_type;
GType slave_gtype = G_TYPE_INVALID;
NMSetting *setting;
slave_type = nm_setting_connection_get_slave_type (s_con);
if (!slave_type)
return;
if (g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) == 0)
slave_gtype = NM_TYPE_SETTING_BRIDGE_PORT;
else if (g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME) == 0)
slave_gtype = NM_TYPE_SETTING_TEAM_PORT;
if (slave_gtype != G_TYPE_INVALID && !nm_connection_get_setting (connection, slave_gtype)) {
setting = (NMSetting *) g_object_new (slave_gtype, NULL);
g_assert (setting);
nm_connection_add_setting (connection, setting);
}
}
NMConnection *
nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
{
@ -1237,7 +1213,6 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
gsize length;
int i;
gboolean vpn_secrets = FALSE;
const char *ctype;
GError *verify_error = NULL;
if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) {
@ -1274,49 +1249,28 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
nm_connection_add_setting (connection, setting);
}
/* Make sure that we have the base device type and slave type settings
* even if the keyfile didn't include it, which can happen when the
* setting in question is all default values (like ethernet where
* the MAC address isn't given, or VLAN when the VLAN ID is zero, or
* bridge port with all default settings).
*/
s_con = nm_connection_get_setting_connection (connection);
if (s_con) {
ctype = nm_setting_connection_get_connection_type (s_con);
if (ctype) {
setting = nm_connection_get_setting_by_name (connection, ctype);
if (!setting) {
NMSetting *base_setting;
GType base_setting_type;
if (!s_con) {
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
nm_connection_add_setting (connection, NM_SETTING (s_con));
}
base_setting_type = nm_setting_lookup_type (ctype);
if (base_setting_type != G_TYPE_INVALID) {
base_setting = (NMSetting *) g_object_new (base_setting_type, NULL);
g_assert (base_setting);
nm_connection_add_setting (connection, base_setting);
}
}
}
/* Make sure that we have 'id' even if not explictly specified in the keyfile */
if (!nm_setting_connection_get_id (s_con)) {
char *base_name;
/* Make sure that we have 'id' even if not explictly specified in the keyfile */
if (!nm_setting_connection_get_id (s_con)) {
char *base_name;
base_name = g_path_get_basename (filename);
g_object_set (s_con, NM_SETTING_CONNECTION_ID, base_name, NULL);
g_free (base_name);
}
base_name = g_path_get_basename (filename);
g_object_set (s_con, NM_SETTING_CONNECTION_ID, base_name, NULL);
g_free (base_name);
}
/* Make sure that we have 'uuid' even if not explictly specified in the keyfile */
if (!nm_setting_connection_get_uuid (s_con)) {
char *hashed_uuid;
/* Make sure that we have 'uuid' even if not explictly specified in the keyfile */
if (!nm_setting_connection_get_uuid (s_con)) {
char *hashed_uuid;
hashed_uuid = nm_utils_uuid_generate_from_string (filename);
g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
g_free (hashed_uuid);
}
ensure_slave_setting (connection);
hashed_uuid = nm_utils_uuid_generate_from_string (filename);
g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
g_free (hashed_uuid);
}
/* Handle vpn secrets after the 'vpn' setting was read */
@ -1330,8 +1284,8 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
g_strfreev (groups);
/* Verify the connection */
if (!nm_connection_verify (connection, &verify_error)) {
/* Normalize and verify the connection */
if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) {
g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
"invalid or missing connection property '%s/%s'",
verify_error ? g_type_name (nm_setting_lookup_type_by_quark (verify_error->domain)) : "(unknown)",

View file

@ -21,6 +21,12 @@ KEYFILES = \
Test_Bridge_Component \
Test_New_Wired_Group_Name \
Test_New_Wireless_Group_Names \
Test_minimal_1 \
Test_minimal_2 \
Test_minimal_slave_1 \
Test_minimal_slave_2 \
Test_minimal_slave_3 \
Test_minimal_slave_4 \
Test_Missing_Vlan_Setting \
Test_Missing_ID_UUID

View file

@ -0,0 +1,2 @@
[connection]
type=802-3-ethernet

View file

@ -0,0 +1 @@
[802-3-ethernet]

View file

@ -0,0 +1,4 @@
[connection]
type=802-3-ethernet
master=br0
slave-type=bridge

View file

@ -0,0 +1,7 @@
[connection]
master=br0
[802-3-ethernet]
[bridge-port]

View file

@ -0,0 +1,4 @@
[connection]
master=br0
slave-type=bridge
[802-3-ethernet]

View file

@ -0,0 +1,4 @@
[connection]
type=802-3-ethernet
master=br0
[bridge-port]

View file

@ -114,6 +114,22 @@ check_ip6_route (NMSettingIP6Config *config, int idx, const char *destination_st
g_assert (nm_ip6_route_get_metric (route) == metric);
}
static NMConnection *
keyfile_read_connection_from_file (const char *filename)
{
GError *error = NULL;
NMConnection *connection;
g_assert (filename);
connection = nm_keyfile_plugin_connection_from_file (filename, &error);
g_assert_no_error (error);
nmtst_assert_connection_verifies_without_normalization (connection);
return connection;
}
static void
test_read_valid_wired_connection (void)
{
@ -1376,8 +1392,7 @@ test_write_string_ssid (void)
reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
"connection-write", "written and re-read connection weren't the same");
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -1501,8 +1516,7 @@ test_write_intlist_ssid (void)
g_assert_no_error (error);
g_assert (reread);
success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
g_assert (success);
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -1653,8 +1667,7 @@ test_write_intlike_ssid (void)
g_assert_no_error (error);
g_assert (reread);
success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
g_assert (success);
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -1741,8 +1754,7 @@ test_write_intlike_ssid_2 (void)
g_assert_no_error (error);
g_assert (reread);
success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
g_assert (success);
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -1996,8 +2008,7 @@ test_write_bt_dun_connection (void)
reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
"connection-write", "written and re-read connection weren't the same");
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -2230,8 +2241,7 @@ test_write_gsm_connection (void)
reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
"connection-write", "written and re-read connection weren't the same");
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
g_clear_error (&error);
unlink (testfile);
@ -3224,7 +3234,7 @@ test_write_new_wired_group_name (void)
reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
g_assert_no_error (error);
g_assert (reread);
g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
/* Look at the keyfile itself to ensure we wrote out the new group names and type */
kf = g_key_file_new ();
@ -3354,7 +3364,7 @@ test_write_new_wireless_group_names (void)
reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
g_assert_no_error (error);
g_assert (reread);
g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
/* Look at the keyfile itself to ensure we wrote out the new group names and type */
kf = g_key_file_new ();
@ -3428,73 +3438,155 @@ test_read_missing_id_uuid (void)
g_object_unref (connection);
}
static void
test_read_minimal ()
{
NMConnection *connection = NULL;
gs_unref_object NMConnection *con_archetype = NULL;
NMSettingConnection *s_con;
con_archetype = nmtst_create_minimal_connection ("Test_minimal_x",
"a15bd68f-c32b-40b8-8d27-49e472a85919",
NM_SETTING_WIRED_SETTING_NAME,
&s_con);
nmtst_connection_normalize (con_archetype);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_1");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_2");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
}
static void
test_read_minimal_slave ()
{
NMConnection *connection = NULL;
gs_unref_object NMConnection *con_archetype = NULL;
NMSettingConnection *s_con;
con_archetype = nmtst_create_minimal_connection ("Test_minimal_slave_x",
"a56b4ca5-7075-43d4-82c7-5d0cb15f7654",
NM_SETTING_WIRED_SETTING_NAME,
&s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "br0",
NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge",
NULL);
nmtst_connection_normalize (con_archetype);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_1");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_2");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_3");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_4");
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection),
NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection),
NULL);
nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE);
g_clear_object (&connection);
}
NMTST_DEFINE ();
int main (int argc, char **argv)
{
char *base;
nmtst_init_assert_logging (&argc, &argv);
/* The tests */
test_read_valid_wired_connection ();
test_write_wired_connection ();
g_test_add_func ("/keyfile/test_read_valid_wired_connection ", test_read_valid_wired_connection);
g_test_add_func ("/keyfile/test_write_wired_connection ", test_write_wired_connection);
test_read_ip6_wired_connection ();
test_write_ip6_wired_connection ();
g_test_add_func ("/keyfile/test_read_ip6_wired_connection ", test_read_ip6_wired_connection);
g_test_add_func ("/keyfile/test_write_ip6_wired_connection ", test_write_ip6_wired_connection);
test_read_wired_mac_case ();
test_read_mac_old_format ();
test_read_mac_ib_old_format ();
g_test_add_func ("/keyfile/test_read_wired_mac_case ", test_read_wired_mac_case);
g_test_add_func ("/keyfile/test_read_mac_old_format ", test_read_mac_old_format);
g_test_add_func ("/keyfile/test_read_mac_ib_old_format ", test_read_mac_ib_old_format);
test_read_valid_wireless_connection ();
test_write_wireless_connection ();
g_test_add_func ("/keyfile/test_read_valid_wireless_connection ", test_read_valid_wireless_connection);
g_test_add_func ("/keyfile/test_write_wireless_connection ", test_write_wireless_connection);
test_read_string_ssid ();
test_write_string_ssid ();
g_test_add_func ("/keyfile/test_read_string_ssid ", test_read_string_ssid);
g_test_add_func ("/keyfile/test_write_string_ssid ", test_write_string_ssid);
test_read_intlist_ssid ();
test_write_intlist_ssid ();
g_test_add_func ("/keyfile/test_read_intlist_ssid ", test_read_intlist_ssid);
g_test_add_func ("/keyfile/test_write_intlist_ssid ", test_write_intlist_ssid);
test_read_intlike_ssid ();
test_write_intlike_ssid ();
g_test_add_func ("/keyfile/test_read_intlike_ssid ", test_read_intlike_ssid);
g_test_add_func ("/keyfile/test_write_intlike_ssid ", test_write_intlike_ssid);
test_read_intlike_ssid_2 ();
test_write_intlike_ssid_2 ();
g_test_add_func ("/keyfile/test_read_intlike_ssid_2 ", test_read_intlike_ssid_2);
g_test_add_func ("/keyfile/test_write_intlike_ssid_2 ", test_write_intlike_ssid_2);
test_read_bt_dun_connection ();
test_write_bt_dun_connection ();
g_test_add_func ("/keyfile/test_read_bt_dun_connection ", test_read_bt_dun_connection);
g_test_add_func ("/keyfile/test_write_bt_dun_connection ", test_write_bt_dun_connection);
test_read_gsm_connection ();
test_write_gsm_connection ();
g_test_add_func ("/keyfile/test_read_gsm_connection ", test_read_gsm_connection);
g_test_add_func ("/keyfile/test_write_gsm_connection ", test_write_gsm_connection);
test_read_wired_8021x_tls_blob_connection ();
test_read_wired_8021x_tls_bad_path_connection ();
g_test_add_func ("/keyfile/test_read_wired_8021x_tls_blob_connection ", test_read_wired_8021x_tls_blob_connection);
g_test_add_func ("/keyfile/test_read_wired_8021x_tls_bad_path_connection ", test_read_wired_8021x_tls_bad_path_connection);
test_read_wired_8021x_tls_old_connection ();
test_read_wired_8021x_tls_new_connection ();
test_write_wired_8021x_tls_connection_path ();
test_write_wired_8021x_tls_connection_blob ();
g_test_add_func ("/keyfile/test_read_wired_8021x_tls_old_connection ", test_read_wired_8021x_tls_old_connection);
g_test_add_func ("/keyfile/test_read_wired_8021x_tls_new_connection ", test_read_wired_8021x_tls_new_connection);
g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_path ", test_write_wired_8021x_tls_connection_path);
g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_blob ", test_write_wired_8021x_tls_connection_blob);
test_read_infiniband_connection ();
test_write_infiniband_connection ();
g_test_add_func ("/keyfile/test_read_infiniband_connection ", test_read_infiniband_connection);
g_test_add_func ("/keyfile/test_write_infiniband_connection ", test_write_infiniband_connection);
test_read_bridge_main ();
test_write_bridge_main ();
test_read_bridge_component ();
test_write_bridge_component ();
g_test_add_func ("/keyfile/test_read_bridge_main ", test_read_bridge_main);
g_test_add_func ("/keyfile/test_write_bridge_main ", test_write_bridge_main);
g_test_add_func ("/keyfile/test_read_bridge_component ", test_read_bridge_component);
g_test_add_func ("/keyfile/test_write_bridge_component ", test_write_bridge_component);
test_read_new_wired_group_name ();
test_write_new_wired_group_name ();
test_read_new_wireless_group_names ();
test_write_new_wireless_group_names ();
g_test_add_func ("/keyfile/test_read_new_wired_group_name ", test_read_new_wired_group_name);
g_test_add_func ("/keyfile/test_write_new_wired_group_name ", test_write_new_wired_group_name);
g_test_add_func ("/keyfile/test_read_new_wireless_group_names ", test_read_new_wireless_group_names);
g_test_add_func ("/keyfile/test_write_new_wireless_group_names ", test_write_new_wireless_group_names);
test_read_missing_vlan_setting ();
test_read_missing_id_uuid ();
g_test_add_func ("/keyfile/test_read_missing_vlan_setting ", test_read_missing_vlan_setting);
g_test_add_func ("/keyfile/test_read_missing_id_uuid ", test_read_missing_id_uuid);
base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base);
g_free (base);
return 0;
g_test_add_func ("/keyfile/test_read_minimal", test_read_minimal);
g_test_add_func ("/keyfile/test_read_minimal_slave", test_read_minimal_slave);
return g_test_run ();
}