libnm: fix normalizing and verifying OVS connections

Normalizing can be complicated, as settings depend on each other and possibly
conflict.

That is, because verify() must exactly anticipate whether normalization will
succeed and how the result will look like. That is because we only want to
modify the connection, if we are sure that the result will verify.

Hence, verify() and normalize() are strongly related. The implementation
should not be spread out between NMSettingOvsInterface:verify(),
NMSettingOvsPatch:verify() and _normalize_ovs_interface_type().

Also, add some unit-tests.
This commit is contained in:
Thomas Haller 2017-10-27 14:30:18 +02:00 committed by Lubomir Rintel
parent 93315d01da
commit 4199c976da
7 changed files with 568 additions and 93 deletions

View file

@ -34,4 +34,10 @@ const char *_nm_connection_detect_bluetooth_type (NMConnection *self);
gboolean _nm_connection_verify_required_interface_name (NMConnection *connection,
GError **error);
int _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
GError **error);
#endif /* __NM_CONNECTION_PRIVATE_H__ */

View file

@ -1114,33 +1114,21 @@ static gboolean
_normalize_ovs_interface_type (NMConnection *self, GHashTable *parameters)
{
NMSettingOvsInterface *s_ovs_interface = nm_connection_get_setting_ovs_interface (self);
NMSettingConnection *s_con = nm_connection_get_setting_connection (self);
const char *interface_type;
gboolean modified;
int v;
if (strcmp (nm_connection_get_connection_type (self), NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) {
/* OpenVSwitch managed interface. */
if (nm_connection_get_setting_ovs_patch (self))
interface_type = "patch";
else
interface_type = "internal";
} else if (g_strcmp0 (nm_setting_connection_get_slave_type (s_con), NM_SETTING_OVS_PORT_SETTING_NAME) == 0) {
/* A regular device enslaved to a port. */
interface_type = "";
} else {
/* Something else. */
if (!s_ovs_interface)
return FALSE;
}
if (!s_ovs_interface) {
s_ovs_interface = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (self, NM_SETTING (s_ovs_interface));
}
v = _nm_setting_ovs_interface_verify_interface_type (s_ovs_interface,
self,
TRUE,
&modified,
NULL);
if (v != TRUE)
g_return_val_if_reached (modified);
g_object_set (s_ovs_interface,
NM_SETTING_OVS_INTERFACE_TYPE, interface_type,
NULL);
return TRUE;
return modified;
}
static gboolean
@ -1465,6 +1453,7 @@ nm_connection_normalize (NMConnection *connection,
NM_CONNECTION_ERROR_FAILED,
_("Unexpected failure to normalize the connection"));
}
g_warning ("connection did not verify after normalization: %s", error ? (*error)->message : "??");
g_return_val_if_reached (FALSE);
}

View file

@ -859,6 +859,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
gboolean is_slave;
const char *slave_setting_type;
NMSetting *normerr_base_type = NULL;
const char *type;
const char *slave_type;
const char *normerr_slave_setting_type = NULL;
const char *normerr_missing_slave_type = NULL;
const char *normerr_missing_slave_type_port = NULL;
@ -904,8 +906,10 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (!priv->type) {
if (!connection || !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) {
type = priv->type;
if (!type) {
if ( !connection
|| !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
@ -913,10 +917,11 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
type = nm_setting_get_name (normerr_base_type);
} else {
GType base_type;
if (!priv->type[0]) {
if (!type[0]) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -925,21 +930,21 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
base_type = nm_setting_lookup_type (priv->type);
base_type = nm_setting_lookup_type (type);
if ( base_type == G_TYPE_INVALID
|| _nm_setting_type_get_base_type_priority (base_type) == NM_SETTING_PRIORITY_INVALID) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("connection type '%s' is not valid"),
priv->type);
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 ( connection
&& !nm_connection_get_setting_by_name (connection, priv->type)) {
&& !nm_connection_get_setting_by_name (connection, type)) {
NMSetting *s_base;
NMConnection *connection2;
@ -952,7 +957,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_object_unref (connection2);
if (!normerr_base_setting) {
_set_error_missing_base_setting (error, priv->type);
_set_error_missing_base_setting (error, type);
return FALSE;
}
}
@ -960,13 +965,14 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
is_slave = FALSE;
slave_setting_type = NULL;
if (priv->slave_type) {
is_slave = _nm_setting_slave_type_is_valid (priv->slave_type, &slave_setting_type);
slave_type = priv->slave_type;
if (slave_type) {
is_slave = _nm_setting_slave_type_is_valid (slave_type, &slave_setting_type);
if (!is_slave) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("Unknown slave type '%s'"), priv->slave_type);
_("Unknown slave type '%s'"), slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
@ -986,8 +992,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
&& !nm_connection_get_setting_by_name (connection, slave_setting_type))
normerr_slave_setting_type = slave_setting_type;
} else {
nm_assert (!slave_type);
if (priv->master) {
const char *slave_type;
NMSetting *s_port;
if ( connection
@ -1006,8 +1012,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if ( g_strcmp0 (priv->type, NM_SETTING_OVS_PORT_SETTING_NAME) != 0
&& g_strcmp0 (priv->slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME) == 0) {
if ( nm_streq0 (type, NM_SETTING_OVS_PORT_SETTING_NAME)
&& !nm_streq0 (slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,

View file

@ -78,6 +78,173 @@ nm_setting_ovs_interface_get_interface_type (NMSettingOvsInterface *self)
/*****************************************************************************/
int
_nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
GError **error)
{
gboolean has_patch;
const char *type;
const char *connection_type;
gboolean is_ovs_connection_type;
gboolean missing_patch_setting = FALSE;
g_return_val_if_fail (NM_IS_SETTING_OVS_INTERFACE (self), FALSE);
if (normalize) {
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
nm_assert (self == nm_connection_get_setting_ovs_interface (connection));
} else
g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), FALSE);
NM_SET_OUT (out_modified, FALSE);
type = self ? self->type : NULL;
if ( type
&& !NM_IN_STRSET (type,
"internal",
"system",
"patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid interface type"),
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (!connection)
return TRUE;
connection_type = nm_connection_get_connection_type (connection);
if (!connection_type) {
/* if we have an ovs-interface, then the connection type must be either
* "ovs-interface" (for non "system" type) or anything else (for "system" type).
*
* The connection type usually can be normalized based on the presence of a
* base setting. However, in this case, if the connection type is missing,
* that is too complicate to guess what the user wanted.
*
* Require the use to be explicit and fail. */
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting needs connection.type explicitly set"),
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
if (nm_streq (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
if ( type
&& nm_streq (type, "system")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection of type '%s' cannot have ovs-interface.type \"system\""),
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
is_ovs_connection_type = TRUE;
} else {
if ( type
&& !nm_streq (type, "system")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection of type '%s' cannot have an ovs-interface.type \"%s\""),
connection_type,
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
is_ovs_connection_type = FALSE;
}
has_patch = !!nm_connection_get_setting_by_name (connection, NM_SETTING_OVS_PATCH_SETTING_NAME);
if (has_patch) {
if (!is_ovs_connection_type) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting must be of connection.type \"ovs-interface\" but is \"%s\""),
NM_SETTING_OVS_PATCH_SETTING_NAME,
connection_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (type) {
if (!nm_streq (type, "patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting needs to be of 'patch' interface type, not '%s'"),
NM_SETTING_OVS_PATCH_SETTING_NAME,
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
return TRUE;
}
type = "patch";
goto normalize;
} else {
if (nm_streq0 (type, "patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("A connection with ovs-interface.type '%s' setting a 'ovs-patch' setting"),
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
}
if (type)
return TRUE;
if (is_ovs_connection_type)
type = "internal";
else
type = "system";
normalize:
if (!normalize) {
if (!self) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("Missing ovs interface setting"));
g_prefix_error (error, "%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME);
} else {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("Missing ovs interface type"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
}
if (missing_patch_setting) {
}
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (!self) {
self = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (connection, NM_SETTING (self));
}
g_object_set (self,
NM_SETTING_OVS_INTERFACE_TYPE, type,
NULL);
NM_SET_OUT (out_modified, TRUE);
return TRUE;
}
static int
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@ -109,7 +276,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
slave_type = nm_setting_connection_get_slave_type (s_con);
if ( slave_type
&& strcmp (slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) {
&& !nm_streq (slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -122,30 +289,11 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (!NM_IN_STRSET (self->type, "internal", "system", "patch", "", NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid interface type"),
self->type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (connection) {
if ( g_strcmp0 (self->type, "patch") == 0
&& !nm_connection_get_setting_ovs_patch (connection)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection of 'patch' interface type needs a '%s' setting."),
NM_SETTING_OVS_PATCH_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
}
return TRUE;
return _nm_setting_ovs_interface_verify_interface_type (self,
connection,
FALSE,
NULL,
error);
}
/*****************************************************************************/

View file

@ -115,37 +115,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if (connection) {
NMSettingOvsInterface *s_ovs_interface;
const char *interface_type = NULL;
s_ovs_interface = nm_connection_get_setting_ovs_interface (connection);
if (s_ovs_interface)
interface_type = nm_setting_ovs_interface_get_interface_type (s_ovs_interface);
if (interface_type && strcmp (interface_type, "patch") != 0) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting needs to be of 'patch' interface type, not '%s'"),
NM_SETTING_OVS_PATCH_SETTING_NAME,
interface_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (!interface_type) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting needs to be of 'patch' interface type"),
NM_SETTING_OVS_PATCH_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
}
return TRUE;
}

View file

@ -219,7 +219,7 @@ _nm_setting_get_base_type_priority (NMSetting *setting)
GType
nm_setting_lookup_type (const char *name)
{
SettingInfo *info;
const SettingInfo *info;
g_return_val_if_fail (name, G_TYPE_INVALID);

View file

@ -4654,6 +4654,344 @@ test_connection_normalize_shared_addresses (void)
g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.1.1.1");
}
static void
test_connection_normalize_ovs_interface_type_system (gconstpointer test_data)
{
const guint TEST_CASE = GPOINTER_TO_UINT (test_data);
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
NMSettingOvsInterface *s_ovs_if;
con = nmtst_create_minimal_connection ("test_connection_normalize_ovs_interface_type_system",
NULL,
NM_SETTING_WIRED_SETTING_NAME, &s_con);
switch (TEST_CASE) {
case 1:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
s_ovs_if = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_if);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "system");
break;
case 2:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "system");
break;
case 3:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
break;
case 4:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
/* the setting doesn't verify, because the interface-type must be "system". */
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 5:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
break;
case 6:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 7:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME,
NULL);
nm_connection_add_setting (con, nm_setting_bridge_port_new ());
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
default:
g_assert_not_reached ();
break;
}
}
static void
test_connection_normalize_ovs_interface_type_ovs_interface (gconstpointer test_data)
{
const guint TEST_CASE = GPOINTER_TO_UINT (test_data);
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
NMSettingOvsInterface *s_ovs_if;
NMSettingOvsPatch *s_ovs_patch;
NMSettingIP4Config *s_ip4;
NMSettingIP6Config *s_ip6;
con = nmtst_create_minimal_connection ("test_connection_normalize_ovs_interface_type_ovs_interface",
NULL,
NM_SETTING_OVS_INTERFACE_SETTING_NAME, &s_con);
s_ovs_if = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_if);
switch (TEST_CASE) {
case 1:
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 2:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 3:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 4:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 5:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nm_connection_add_setting (con, nm_setting_ip4_config_new ());
nm_connection_add_setting (con, nm_setting_ip6_config_new ());
nm_connection_add_setting (con, nm_setting_proxy_new ());
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting_ip4_config (con));
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (con));
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, "auto",
NULL);
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, "auto",
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
break;
case 6:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nmtst_assert_connection_verifies_and_normalizable (con);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 7:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 8:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "bogus",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 9:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING);
break;
case 10:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nm_connection_add_setting (con, nm_setting_ovs_patch_new ());
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
break;
case 11:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nm_connection_add_setting (con, nm_setting_ovs_patch_new ());
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
break;
case 12:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
s_ovs_patch = NM_SETTING_OVS_PATCH (nm_setting_ovs_patch_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_patch));
g_object_set (s_ovs_patch,
NM_SETTING_OVS_PATCH_PEER, "1.2.3.4",
NULL);
nmtst_assert_connection_verifies_and_normalizable (con);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME,
NM_SETTING_OVS_PATCH_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "patch");
break;
default:
g_assert_not_reached ();
}
}
static void
test_setting_ip4_gateway (void)
{
@ -6540,6 +6878,25 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_connection_normalize_gateway_never_default", test_connection_normalize_gateway_never_default);
g_test_add_func ("/core/general/test_connection_normalize_may_fail", test_connection_normalize_may_fail);
g_test_add_func ("/core/general/test_connection_normalize_shared_addresses", test_connection_normalize_shared_addresses);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/1", GUINT_TO_POINTER (1), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/2", GUINT_TO_POINTER (2), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/3", GUINT_TO_POINTER (3), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/4", GUINT_TO_POINTER (4), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/5", GUINT_TO_POINTER (5), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/6", GUINT_TO_POINTER (6), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/7", GUINT_TO_POINTER (7), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/1", GUINT_TO_POINTER (1), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/2", GUINT_TO_POINTER (2), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/3", GUINT_TO_POINTER (3), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/4", GUINT_TO_POINTER (4), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/5", GUINT_TO_POINTER (5), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/6", GUINT_TO_POINTER (6), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/7", GUINT_TO_POINTER (7), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/8", GUINT_TO_POINTER (8), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/9", GUINT_TO_POINTER (9), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/10", GUINT_TO_POINTER (10), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/11", GUINT_TO_POINTER (11), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/12", GUINT_TO_POINTER (12), test_connection_normalize_ovs_interface_type_ovs_interface);
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);