summary refs log tree commit diff
path: root/src/platform/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
committerMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
commita54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch)
tree6a32883bd916c4096357b35298beff6db8bcd0b5 /src/platform/tests
parent45e8e1149027529194982212c804c0468aa01d98 (diff)
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'src/platform/tests')
-rw-r--r--src/platform/tests/meson.build2
-rw-r--r--src/platform/tests/test-common.c5
-rw-r--r--src/platform/tests/test-link.c10
-rw-r--r--src/platform/tests/test-tc.c223
4 files changed, 235 insertions, 5 deletions
diff --git a/src/platform/tests/meson.build b/src/platform/tests/meson.build
index 4a50bca9..f96850cc 100644
--- a/src/platform/tests/meson.build
+++ b/src/platform/tests/meson.build
@@ -14,6 +14,8 @@ test_units = [
   ['test-platform-general', 'test-platform-general.c', test_c_flags, default_test_timeout],
   ['test-route-fake', 'test-route.c', test_fake_c_flags, default_test_timeout],
   ['test-route-linux', 'test-route.c', test_linux_c_flags, default_test_timeout],
+  ['test-tc-fake', 'test-tc.c', test_fake_c_flags, default_test_timeout],
+  ['test-tc-linux', 'test-tc.c', test_linux_c_flags, default_test_timeout],
 ]
 
 foreach test_unit: test_units
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index f28dfa3a..9f6a29bc 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -557,6 +557,7 @@ nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec)
 {
 	WaitForSignalData data = { 0 };
 	gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route;
+	gulong id_qdisc, id_tfilter;
 
 	_init_platform (&platform, FALSE);
 
@@ -567,6 +568,8 @@ nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec)
 	id_ip6_address = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
 	id_ip4_route   = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
 	id_ip6_route   = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
+	id_qdisc       = g_signal_connect (platform, NM_PLATFORM_SIGNAL_QDISC_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
+	id_tfilter     = g_signal_connect (platform, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
 
 	/* if timeout_msec is negative, it means the wait-time already expired.
 	 * Maybe, we should do nothing and return right away, without even
@@ -589,6 +592,8 @@ nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec)
 	g_assert (nm_clear_g_signal_handler (platform, &id_ip6_address));
 	g_assert (nm_clear_g_signal_handler (platform, &id_ip4_route));
 	g_assert (nm_clear_g_signal_handler (platform, &id_ip6_route));
+	g_assert (nm_clear_g_signal_handler (platform, &id_tfilter));
+	g_assert (nm_clear_g_signal_handler (platform, &id_qdisc));
 
 	nm_clear_pointer (&data.loop, g_main_loop_unref);
 
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index ea4a2c5a..d7285c83 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -3290,14 +3290,14 @@ test_ethtool_features_get (void)
 		g_ptr_array_add (gfree_keeper, requested);
 
 		if (i_run == 0) {
-			requested[NM_ETHTOOL_ID_FEATURE_RX]                    = NM_TERNARY_FALSE;
-			requested[NM_ETHTOOL_ID_FEATURE_TSO]                   = NM_TERNARY_FALSE;
-			requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION]  = NM_TERNARY_FALSE;
+			requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_RX)] = NM_TERNARY_FALSE;
+			requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE;
+			requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = NM_TERNARY_FALSE;
 		} else if (i_run == 1)
 			do_set = FALSE;
 		else if (i_run == 2) {
-			requested[NM_ETHTOOL_ID_FEATURE_TSO]                   = NM_TERNARY_FALSE;
-			requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION]  = NM_TERNARY_TRUE;
+			requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE;
+			requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = NM_TERNARY_TRUE;
 		} else if (i_run == 3)
 			do_set = FALSE;
 
diff --git a/src/platform/tests/test-tc.c b/src/platform/tests/test-tc.c
new file mode 100644
index 00000000..0c90fcfa
--- /dev/null
+++ b/src/platform/tests/test-tc.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: LGPL-2.1+
+
+#include "nm-default.h"
+
+#include <linux/pkt_sched.h>
+
+#include "nm-test-utils-core.h"
+#include "platform/nmp-object.h"
+#include "platform/nmp-netns.h"
+#include "platform/nm-platform-utils.h"
+#include "test-common.h"
+
+static NMPObject *
+qdisc_new (int ifindex, const char *kind, guint32 parent)
+{
+	NMPObject *obj;
+
+	obj = nmp_object_new (NMP_OBJECT_TYPE_QDISC, NULL);
+	obj->qdisc = (NMPlatformQdisc) {
+		.ifindex = ifindex,
+		.kind = kind,
+		.parent = parent,
+	};
+
+	return obj;
+}
+
+static GPtrArray *
+qdiscs_lookup (int ifindex)
+{
+	NMPLookup lookup;
+
+	return nm_platform_lookup_clone (NM_PLATFORM_GET,
+	                                 nmp_lookup_init_object (&lookup,
+	                                                         NMP_OBJECT_TYPE_QDISC,
+	                                                         ifindex),
+	                                 NULL, NULL);
+}
+
+static void
+test_qdisc1 (void)
+{
+	int ifindex;
+	gs_unref_ptrarray GPtrArray *known = NULL;
+	gs_unref_ptrarray GPtrArray *plat = NULL;
+	NMPObject *obj;
+	NMPlatformQdisc *qdisc;
+
+	ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	g_assert_cmpint (ifindex, >, 0);
+
+	nmtstp_run_command       ("tc qdisc del dev %s root", DEVICE_NAME);
+	nmtstp_run_command_check ("tc qdisc add dev %s root sfq", DEVICE_NAME);
+
+	nmtstp_wait_for_signal (NM_PLATFORM_GET, 0);
+
+	known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+	g_ptr_array_add (known, qdisc_new (ifindex, "fq_codel", TC_H_ROOT));
+	g_ptr_array_add (known, qdisc_new (ifindex, "ingress", TC_H_INGRESS));
+
+	g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known));
+	plat = qdiscs_lookup (ifindex);
+	g_assert (plat);
+	g_assert_cmpint (plat->len, ==, 2);
+
+	obj = plat->pdata[0];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT);
+	g_assert_cmpstr (qdisc->kind, ==, "fq_codel");
+
+	obj = plat->pdata[1];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpint (qdisc->parent, ==, TC_H_INGRESS);
+	g_assert_cmpstr (qdisc->kind, ==, "ingress");
+}
+
+static void
+test_qdisc_fq_codel (void)
+{
+	int ifindex;
+	gs_unref_ptrarray GPtrArray *known = NULL;
+	gs_unref_ptrarray GPtrArray *plat = NULL;
+	NMPObject *obj;
+	NMPlatformQdisc *qdisc;
+
+	ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	g_assert_cmpint (ifindex, >, 0);
+
+	nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME);
+
+	nmtstp_wait_for_signal (NM_PLATFORM_GET, 0);
+
+	known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+	obj = qdisc_new (ifindex, "fq_codel", TC_H_ROOT);
+	obj->qdisc.handle = TC_H_MAKE (0x8142 << 16, 0);
+	obj->qdisc.fq_codel.limit = 2048;
+	obj->qdisc.fq_codel.flows = 64;
+	obj->qdisc.fq_codel.quantum = 1000;
+	g_ptr_array_add (known, obj);
+
+	g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known));
+	plat = qdiscs_lookup (ifindex);
+	g_assert (plat);
+	g_assert_cmpint (plat->len, ==, 1);
+
+	obj = plat->pdata[0];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpstr (qdisc->kind, ==, "fq_codel");
+	g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8142 << 16, 0));
+	g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT);
+	g_assert_cmpint (qdisc->fq_codel.limit, ==, 2048);
+	g_assert_cmpint (qdisc->fq_codel.flows, ==, 64);
+	g_assert_cmpint (qdisc->fq_codel.quantum, ==, 1000);
+}
+
+static void
+test_qdisc_sfq (void)
+{
+	int ifindex;
+	gs_unref_ptrarray GPtrArray *known = NULL;
+	gs_unref_ptrarray GPtrArray *plat = NULL;
+	NMPObject *obj;
+	NMPlatformQdisc *qdisc;
+
+	ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	g_assert_cmpint (ifindex, >, 0);
+
+	nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME);
+
+	nmtstp_wait_for_signal (NM_PLATFORM_GET, 0);
+
+	known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+	obj = qdisc_new (ifindex, "sfq", TC_H_ROOT);
+	obj->qdisc.handle = TC_H_MAKE (0x8143 << 16, 0);
+	obj->qdisc.sfq.perturb_period = 10;
+	obj->qdisc.sfq.quantum = 1540;
+	obj->qdisc.sfq.flows = 256;
+	g_ptr_array_add (known, obj);
+
+	g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known));
+	plat = qdiscs_lookup (ifindex);
+	g_assert (plat);
+	g_assert_cmpint (plat->len, ==, 1);
+
+	obj = plat->pdata[0];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpstr (qdisc->kind, ==, "sfq");
+	g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8143 << 16, 0));
+	g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT);
+	g_assert_cmpint (qdisc->sfq.perturb_period, ==, 10);
+	g_assert_cmpint (qdisc->sfq.quantum, ==, 1540);
+	g_assert_cmpint (qdisc->sfq.flows, ==, 256);
+}
+
+static void
+test_qdisc_tbf (void)
+{
+	int ifindex;
+	gs_unref_ptrarray GPtrArray *known = NULL;
+	gs_unref_ptrarray GPtrArray *plat = NULL;
+	NMPObject *obj;
+	NMPlatformQdisc *qdisc;
+
+	ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	g_assert_cmpint (ifindex, >, 0);
+
+	nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME);
+
+	nmtstp_wait_for_signal (NM_PLATFORM_GET, 0);
+
+	known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+	obj = qdisc_new (ifindex, "tbf", TC_H_ROOT);
+	obj->qdisc.handle = TC_H_MAKE (0x8143 << 16, 0);
+	obj->qdisc.tbf.rate = 1000000;
+	obj->qdisc.tbf.burst = 2000;
+	obj->qdisc.tbf.limit = 3000;
+	g_ptr_array_add (known, obj);
+
+	obj = qdisc_new (ifindex, "sfq", TC_H_MAKE (0x8143 << 16, 0));
+	obj->qdisc.handle = TC_H_MAKE (0x8005 << 16, 0);
+	g_ptr_array_add (known, obj);
+
+	g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known));
+	plat = qdiscs_lookup (ifindex);
+	g_assert (plat);
+	g_assert_cmpint (plat->len, ==, 2);
+
+	obj = plat->pdata[0];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpstr (qdisc->kind, ==, "tbf");
+	g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8143 << 16, 0));
+	g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT);
+	g_assert_cmpint (qdisc->tbf.rate, ==, 1000000);
+	g_assert_cmpint (qdisc->tbf.burst, ==, 2000);
+	g_assert_cmpint (qdisc->tbf.limit, ==, 3000);
+
+	obj = plat->pdata[1];
+	qdisc = NMP_OBJECT_CAST_QDISC (obj);
+	g_assert_cmpstr (qdisc->kind, ==, "sfq");
+	g_assert_cmpint (qdisc->parent, ==, TC_H_MAKE (0x8143 << 16, 0));
+	g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8005 << 16, 0));
+}
+
+/*****************************************************************************/
+
+NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
+
+void
+_nmtstp_init_tests (int *argc, char ***argv)
+{
+	nmtst_init_with_logging (argc, argv, NULL, "ALL");
+}
+
+void
+_nmtstp_setup_tests (void)
+{
+	if (nmtstp_is_root_test ()) {
+		nmtstp_env1_add_test_func ("/link/qdisc/1", test_qdisc1, TRUE);
+		nmtstp_env1_add_test_func ("/link/qdisc/fq_codel", test_qdisc_fq_codel, TRUE);
+		nmtstp_env1_add_test_func ("/link/qdisc/sfq", test_qdisc_sfq, TRUE);
+		nmtstp_env1_add_test_func ("/link/qdisc/tbf", test_qdisc_tbf, TRUE);
+	}
+}