summary refs log tree commit diff
path: root/libnm-core
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-07-01 20:58:23 +0200
committerMichael Biebl <biebl@debian.org>2018-07-01 20:58:23 +0200
commit429393567647935d9123e21fd27a7529d50255eb (patch)
treeb5a99bf0cbbe77fccd7fee81caf71915ccf9eb96 /libnm-core
parent069cb5c3a525ebcc19cc2927964258acaca87b13 (diff)
New upstream version 1.12.0 upstream/1.12.0
Diffstat (limited to 'libnm-core')
-rw-r--r--libnm-core/nm-dbus-interface.h8
-rw-r--r--libnm-core/nm-dbus-types.xml8
-rw-r--r--libnm-core/nm-setting-ovs-bridge.c4
-rw-r--r--libnm-core/nm-setting-ovs-interface.c6
-rw-r--r--libnm-core/nm-setting-ovs-patch.c6
-rw-r--r--libnm-core/nm-setting-ovs-port.c4
-rw-r--r--libnm-core/nm-setting-tc-config.c95
-rw-r--r--libnm-core/nm-simple-connection.c12
-rw-r--r--libnm-core/tests/test-setting.c69
9 files changed, 189 insertions, 23 deletions
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index ba31a379..e7c0bc2c 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -209,9 +209,9 @@ typedef enum {
  * @NM_DEVICE_TYPE_MACSEC: a MACsec interface
  * @NM_DEVICE_TYPE_DUMMY: a dummy interface
  * @NM_DEVICE_TYPE_PPP: a PPP interface
- * @NM_DEVICE_TYPE_OVS_INTERFACE: a OpenVSwitch interface
- * @NM_DEVICE_TYPE_OVS_PORT: a OpenVSwitch port
- * @NM_DEVICE_TYPE_OVS_BRIDGE: a OpenVSwitch bridge
+ * @NM_DEVICE_TYPE_OVS_INTERFACE: a Open vSwitch interface
+ * @NM_DEVICE_TYPE_OVS_PORT: a Open vSwitch port
+ * @NM_DEVICE_TYPE_OVS_BRIDGE: a Open vSwitch bridge
  *
  * #NMDeviceType values indicate the type of hardware represented by a
  * device object.
@@ -550,7 +550,7 @@ typedef enum {
  * @NM_DEVICE_STATE_REASON_NEW_ACTIVATION: New connection activation was enqueued
  * @NM_DEVICE_STATE_REASON_PARENT_CHANGED: the device's parent changed
  * @NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED: the device parent's management changed
- * @NM_DEVICE_STATE_REASON_OVSDB_FAILED: problem communicating with OpenVSwitch database
+ * @NM_DEVICE_STATE_REASON_OVSDB_FAILED: problem communicating with Open vSwitch database
  * @NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE: a duplicate IP address was detected
  * @NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED: The selected IP method is not supported
  *
diff --git a/libnm-core/nm-dbus-types.xml b/libnm-core/nm-dbus-types.xml
index cdb2021e..117e4243 100644
--- a/libnm-core/nm-dbus-types.xml
+++ b/libnm-core/nm-dbus-types.xml
@@ -280,17 +280,17 @@
             <row role="constant">
               <entry role="enum_member_name"><para>NM_DEVICE_TYPE_OVS_INTERFACE</para><para></para></entry>
               <entry role="enum_member_value"><para>= <literal>24</literal></para><para></para></entry>
-              <entry role="enum_member_description"><para>a OpenVSwitch interface</para><para></para></entry>
+              <entry role="enum_member_description"><para>a Open vSwitch interface</para><para></para></entry>
             </row>
             <row role="constant">
               <entry role="enum_member_name"><para>NM_DEVICE_TYPE_OVS_PORT</para><para></para></entry>
               <entry role="enum_member_value"><para>= <literal>25</literal></para><para></para></entry>
-              <entry role="enum_member_description"><para>a OpenVSwitch port</para><para></para></entry>
+              <entry role="enum_member_description"><para>a Open vSwitch port</para><para></para></entry>
             </row>
             <row role="constant">
               <entry role="enum_member_name"><para>NM_DEVICE_TYPE_OVS_BRIDGE</para><para></para></entry>
               <entry role="enum_member_value"><para>= <literal>26</literal></para><para></para></entry>
-              <entry role="enum_member_description"><para>a OpenVSwitch bridge</para><para></para></entry>
+              <entry role="enum_member_description"><para>a Open vSwitch bridge</para><para></para></entry>
             </row>
           </tbody>
         </tgroup>
@@ -1120,7 +1120,7 @@
             <row role="constant">
               <entry role="enum_member_name"><para>NM_DEVICE_STATE_REASON_OVSDB_FAILED</para><para></para></entry>
               <entry role="enum_member_value"><para>= <literal>63</literal></para><para></para></entry>
-              <entry role="enum_member_description"><para>problem communicating with OpenVSwitch database</para><para></para></entry>
+              <entry role="enum_member_description"><para>problem communicating with Open vSwitch database</para><para></para></entry>
             </row>
             <row role="constant">
               <entry role="enum_member_name"><para>NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE</para><para></para></entry>
diff --git a/libnm-core/nm-setting-ovs-bridge.c b/libnm-core/nm-setting-ovs-bridge.c
index fbae95d0..4993d13f 100644
--- a/libnm-core/nm-setting-ovs-bridge.c
+++ b/libnm-core/nm-setting-ovs-bridge.c
@@ -28,10 +28,10 @@
 
 /**
  * SECTION:nm-setting-ovs-bridge
- * @short_description: Describes connection properties for OpenVSwitch bridges.
+ * @short_description: Describes connection properties for Open vSwitch bridges.
  *
  * The #NMSettingOvsBridge object is a #NMSetting subclass that describes properties
- * necessary for OpenVSwitch bridges.
+ * necessary for Open vSwitch bridges.
  **/
 
 enum {
diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c
index 73e1cfc6..ff9e4c1d 100644
--- a/libnm-core/nm-setting-ovs-interface.c
+++ b/libnm-core/nm-setting-ovs-interface.c
@@ -27,10 +27,10 @@
 
 /**
  * SECTION:nm-setting-ovs-interface
- * @short_description: Describes connection properties for OpenVSwitch interfaces.
+ * @short_description: Describes connection properties for Open vSwitch interfaces.
  *
  * The #NMSettingOvsInterface object is a #NMSetting subclass that describes properties
- * necessary for OpenVSwitch interfaces.
+ * necessary for Open vSwitch interfaces.
  **/
 
 enum {
@@ -42,7 +42,7 @@ enum {
 /**
  * NMSettingOvsInterface:
  *
- * OpenVSwitch Interface Settings
+ * Open vSwitch Interface Settings
  */
 struct _NMSettingOvsInterface {
 	NMSetting parent;
diff --git a/libnm-core/nm-setting-ovs-patch.c b/libnm-core/nm-setting-ovs-patch.c
index 3689aecf..980015f2 100644
--- a/libnm-core/nm-setting-ovs-patch.c
+++ b/libnm-core/nm-setting-ovs-patch.c
@@ -28,10 +28,10 @@
 
 /**
  * SECTION:nm-setting-ovs-patch
- * @short_description: Describes connection properties for OpenVSwitch patch interfaces.
+ * @short_description: Describes connection properties for Open vSwitch patch interfaces.
  *
  * The #NMSettingOvsPatch object is a #NMSetting subclass that describes properties
- * necessary for OpenVSwitch interfaces of type "patch".
+ * necessary for Open vSwitch interfaces of type "patch".
  **/
 
 enum {
@@ -195,7 +195,7 @@ nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *setting_class)
 	/**
 	 * NMSettingOvsPatch:peer:
 	 *
-	 * Specifies the unicast destination IP address of a remote OpenVSwitch
+	 * Specifies the unicast destination IP address of a remote Open vSwitch
 	 * bridge port to connect to.
 	 *
 	 * Since: 1.10
diff --git a/libnm-core/nm-setting-ovs-port.c b/libnm-core/nm-setting-ovs-port.c
index 72722b15..b61df0ce 100644
--- a/libnm-core/nm-setting-ovs-port.c
+++ b/libnm-core/nm-setting-ovs-port.c
@@ -28,10 +28,10 @@
 
 /**
  * SECTION:nm-setting-ovs-port
- * @short_description: Describes connection properties for OpenVSwitch ports.
+ * @short_description: Describes connection properties for Open vSwitch ports.
  *
  * The #NMSettingOvsPort object is a #NMSetting subclass that describes properties
- * necessary for OpenVSwitch ports.
+ * necessary for Open vSwitch ports.
  **/
 
 enum {
diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c
index e801e4fd..f50969fb 100644
--- a/libnm-core/nm-setting-tc-config.c
+++ b/libnm-core/nm-setting-tc-config.c
@@ -154,6 +154,19 @@ nm_tc_qdisc_equal (NMTCQdisc *qdisc, NMTCQdisc *other)
 	return TRUE;
 }
 
+static guint
+_nm_tc_qdisc_hash (NMTCQdisc *qdisc)
+{
+	NMHashState h;
+
+	nm_hash_init (&h, 43869703);
+	nm_hash_update_vals (&h,
+	                     qdisc->handle,
+	                     qdisc->parent);
+	nm_hash_update_str0 (&h, qdisc->kind);
+	return nm_hash_complete (&h);
+}
+
 /**
  * nm_tc_qdisc_dup:
  * @qdisc: the #NMTCQdisc
@@ -626,6 +639,38 @@ nm_tc_tfilter_equal (NMTCTfilter *tfilter, NMTCTfilter *other)
 	return TRUE;
 }
 
+static guint
+_nm_tc_tfilter_hash (NMTCTfilter *tfilter)
+{
+	gs_free const char **names = NULL;
+	guint i, attr_hash;
+	GVariant *variant;
+	NMHashState h;
+	guint length;
+
+	nm_hash_init (&h, 63624437);
+	nm_hash_update_vals (&h,
+	                     tfilter->handle,
+	                     tfilter->parent);
+	nm_hash_update_str0 (&h, tfilter->kind);
+	if (tfilter->action) {
+		nm_hash_update_str0 (&h, tfilter->action->kind);
+		names = nm_utils_strdict_get_keys (tfilter->action->attributes, TRUE, &length);
+		for (i = 0; i < length; i++) {
+			nm_hash_update_str (&h, names[i]);
+			variant = g_hash_table_lookup (tfilter->action->attributes, names[i]);
+			if (g_variant_type_is_basic (g_variant_get_type (variant))) {
+				/* g_variant_hash() works only for basic types, thus
+				 * we ignore any non-basic attribute. Actions differing
+				 * only for non-basic attributes will collide. */
+				attr_hash = g_variant_hash (variant);
+				nm_hash_update_val (&h, attr_hash);
+			}
+		}
+	}
+	return nm_hash_complete (&h);
+}
+
 /**
  * nm_tc_tfilter_dup:
  * @tfilter: the #NMTCTfilter
@@ -1138,6 +1183,55 @@ finalize (GObject *object)
 }
 
 static gboolean
+verify (NMSetting *setting, NMConnection *connection, GError **error)
+{
+	NMSettingTCConfig *self = NM_SETTING_TC_CONFIG (setting);
+	guint i;
+
+	if (self->qdiscs->len != 0) {
+		gs_unref_hashtable GHashTable *ht = NULL;
+
+		ht = g_hash_table_new ((GHashFunc) _nm_tc_qdisc_hash,
+		                       (GEqualFunc) nm_tc_qdisc_equal);
+		for (i = 0; i < self->qdiscs->len; i++) {
+			if (!g_hash_table_add (ht, self->qdiscs->pdata[i])) {
+				g_set_error_literal (error,
+				                     NM_CONNECTION_ERROR,
+				                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+				                     _("there are duplicate TC qdiscs"));
+				g_prefix_error (error,
+				                "%s.%s: ",
+				                NM_SETTING_TC_CONFIG_SETTING_NAME,
+				                NM_SETTING_TC_CONFIG_QDISCS);
+				return FALSE;
+			}
+		}
+	}
+
+	if (self->tfilters->len != 0) {
+		gs_unref_hashtable GHashTable *ht = NULL;
+
+		ht = g_hash_table_new ((GHashFunc) _nm_tc_tfilter_hash,
+		                       (GEqualFunc) nm_tc_tfilter_equal);
+		for (i = 0; i < self->tfilters->len; i++) {
+			if (!g_hash_table_add (ht, self->tfilters->pdata[i])) {
+				g_set_error_literal (error,
+				                     NM_CONNECTION_ERROR,
+				                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+				                     _("there are duplicate TC filters"));
+				g_prefix_error (error,
+				                "%s.%s: ",
+				                NM_SETTING_TC_CONFIG_SETTING_NAME,
+				                NM_SETTING_TC_CONFIG_TFILTERS);
+				return FALSE;
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+static gboolean
 compare_property (NMSetting *setting,
                   NMSetting *other,
                   const GParamSpec *prop_spec,
@@ -1502,6 +1596,7 @@ nm_setting_tc_config_class_init (NMSettingTCConfigClass *setting_class)
 	object_class->get_property     = get_property;
 	object_class->finalize         = finalize;
 	parent_class->compare_property = compare_property;
+	parent_class->verify           = verify;
 
 	/* Properties */
 
diff --git a/libnm-core/nm-simple-connection.c b/libnm-core/nm-simple-connection.c
index f06e1aed..9ccdbb21 100644
--- a/libnm-core/nm-simple-connection.c
+++ b/libnm-core/nm-simple-connection.c
@@ -24,6 +24,14 @@
 #include "nm-simple-connection.h"
 #include "nm-setting-private.h"
 
+/**
+ * SECTION:nm-simple-connection
+ * @short_description: An unmanaged connection
+ *
+ * An #NMSimpleConnection does not directly represent a D-Bus-exported connection,
+ * but might be used in the process of creating a new one.
+ **/
+
 static void nm_simple_connection_interface_init (NMConnectionInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NMSimpleConnection, nm_simple_connection, G_TYPE_OBJECT,
@@ -38,9 +46,7 @@ nm_simple_connection_init (NMSimpleConnection *self)
 /**
  * nm_simple_connection_new:
  *
- * Creates a new #NMSimpleConnection object with no #NMSetting objects. An
- * #NMSimpleConnection does not directly represent a D-Bus-exported connection,
- * but might be used in the process of creating a new one.
+ * Creates a new #NMSimpleConnection object with no #NMSetting objects.
  *
  * Returns: (transfer full): the new empty #NMConnection object
  **/
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 6c5c6ad9..e71d6b7c 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -1440,7 +1440,7 @@ test_tc_config_tfilter (void)
 }
 
 static void
-test_tc_config_setting (void)
+test_tc_config_setting_valid (void)
 {
 	gs_unref_object NMSettingTCConfig *s_tc = NULL;
 	NMTCQdisc *qdisc1, *qdisc2;
@@ -1474,6 +1474,70 @@ test_tc_config_setting (void)
 }
 
 static void
+test_tc_config_setting_duplicates (void)
+{
+	gs_unref_ptrarray GPtrArray *qdiscs = NULL;
+	gs_unref_ptrarray GPtrArray *tfilters = NULL;
+	NMSettingConnection *s_con;
+	NMConnection *con;
+	NMSetting *s_tc;
+	NMTCQdisc *qdisc;
+	NMTCTfilter *tfilter;
+	GError *error = NULL;
+
+	con = nmtst_create_minimal_connection ("dummy",
+	                                       NULL,
+	                                       NM_SETTING_DUMMY_SETTING_NAME,
+	                                       &s_con);
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_INTERFACE_NAME, "dummy1",
+	              NULL);
+
+	s_tc = nm_setting_tc_config_new ();
+	nm_connection_add_setting (con, s_tc);
+	qdiscs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_qdisc_unref);
+	tfilters = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_tfilter_unref);
+
+	/* 1. add duplicate qdiscs */
+	qdisc = nm_utils_tc_qdisc_from_str ("handle 1234 parent fff1:1 pfifo_fast", &error);
+	nmtst_assert_success (qdisc, error);
+	g_ptr_array_add (qdiscs, qdisc);
+
+	qdisc = nm_utils_tc_qdisc_from_str ("handle 1234 parent fff1:1 pfifo_fast", &error);
+	nmtst_assert_success (qdisc, error);
+	g_ptr_array_add (qdiscs, qdisc);
+
+	g_object_set (s_tc, NM_SETTING_TC_CONFIG_QDISCS, qdiscs, NULL);
+	nmtst_assert_connection_unnormalizable (con,
+	                                        NM_CONNECTION_ERROR,
+	                                        NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+	/* 2. make qdiscs unique */
+	g_ptr_array_remove_index (qdiscs, 0);
+	g_object_set (s_tc, NM_SETTING_TC_CONFIG_QDISCS, qdiscs, NULL);
+	nmtst_assert_connection_verifies_and_normalizable (con);
+
+	/* 3. add duplicate filters */
+	tfilter = nm_utils_tc_tfilter_from_str ("parent 1234: matchall action simple sdata Hello", &error);
+	nmtst_assert_success (tfilter, error);
+	g_ptr_array_add (tfilters, tfilter);
+
+	tfilter = nm_utils_tc_tfilter_from_str ("parent 1234: matchall action simple sdata Hello", &error);
+	nmtst_assert_success (tfilter, error);
+	g_ptr_array_add (tfilters, tfilter);
+
+	g_object_set (s_tc, NM_SETTING_TC_CONFIG_TFILTERS, tfilters, NULL);
+	nmtst_assert_connection_unnormalizable (con,
+	                                        NM_CONNECTION_ERROR,
+	                                        NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+	/* 4. make filters unique */
+	g_ptr_array_remove_index (tfilters, 0);
+	g_object_set (s_tc, NM_SETTING_TC_CONFIG_TFILTERS, tfilters, NULL);
+	nmtst_assert_connection_verifies_and_normalizable (con);
+}
+
+static void
 test_tc_config_dbus (void)
 {
 	NMConnection *connection1, *connection2;
@@ -1608,7 +1672,8 @@ main (int argc, char **argv)
 	g_test_add_func ("/libnm/settings/tc_config/qdisc", test_tc_config_qdisc);
 	g_test_add_func ("/libnm/settings/tc_config/action", test_tc_config_action);
 	g_test_add_func ("/libnm/settings/tc_config/tfilter", test_tc_config_tfilter);
-	g_test_add_func ("/libnm/settings/tc_config/setting", test_tc_config_setting);
+	g_test_add_func ("/libnm/settings/tc_config/setting/valid", test_tc_config_setting_valid);
+	g_test_add_func ("/libnm/settings/tc_config/setting/duplicates", test_tc_config_setting_duplicates);
 	g_test_add_func ("/libnm/settings/tc_config/dbus", test_tc_config_dbus);
 
 #if WITH_JSON_VALIDATION