diff options
author | Thomas Haller <thaller@redhat.com> | 2017-10-27 14:30:18 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2017-10-30 21:46:55 +0100 |
commit | 4199c976dac21c22773e0c133c42c3b738ca76d2 (patch) | |
tree | a2d505eec660f94c2b91df7fe83bea1ec70a16a3 /libnm-core | |
parent | 93315d01da72c833338e9591d810b44c42da51ef (diff) | |
download | NetworkManager-4199c976dac21c22773e0c133c42c3b738ca76d2.tar.gz |
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.
Diffstat (limited to 'libnm-core')
-rw-r--r-- | libnm-core/nm-connection-private.h | 6 | ||||
-rw-r--r-- | libnm-core/nm-connection.c | 35 | ||||
-rw-r--r-- | libnm-core/nm-setting-connection.c | 32 | ||||
-rw-r--r-- | libnm-core/nm-setting-ovs-interface.c | 198 | ||||
-rw-r--r-- | libnm-core/nm-setting-ovs-patch.c | 31 | ||||
-rw-r--r-- | libnm-core/nm-setting.c | 2 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 357 |
7 files changed, 568 insertions, 93 deletions
diff --git a/libnm-core/nm-connection-private.h b/libnm-core/nm-connection-private.h index 7dd088ace0..ee2d7264b9 100644 --- a/libnm-core/nm-connection-private.h +++ b/libnm-core/nm-connection-private.h @@ -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__ */ diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 720ba8468d..d5e28f7b3e 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -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)); - } - - g_object_set (s_ovs_interface, - NM_SETTING_OVS_INTERFACE_TYPE, interface_type, - NULL); + v = _nm_setting_ovs_interface_verify_interface_type (s_ovs_interface, + self, + TRUE, + &modified, + NULL); + if (v != TRUE) + g_return_val_if_reached (modified); - 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); } diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 4b2c5d501b..28d7a8f6b7 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -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, diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c index 3b214af892..f06db32abb 100644 --- a/libnm-core/nm-setting-ovs-interface.c +++ b/libnm-core/nm-setting-ovs-interface.c @@ -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); } /*****************************************************************************/ diff --git a/libnm-core/nm-setting-ovs-patch.c b/libnm-core/nm-setting-ovs-patch.c index fb1412bf4a..9e38091474 100644 --- a/libnm-core/nm-setting-ovs-patch.c +++ b/libnm-core/nm-setting-ovs-patch.c @@ -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; } diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 590beea5d1..9c8e53aeac 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -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); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 5f4540c57a..0dc7616d6c 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -4655,6 +4655,344 @@ test_connection_normalize_shared_addresses (void) } 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) { NMConnection *conn; @@ -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); |