summary refs log tree commit diff
path: root/src/platform/tests/test-tc.c
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/test-tc.c
parent45e8e1149027529194982212c804c0468aa01d98 (diff)
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'src/platform/tests/test-tc.c')
-rw-r--r--src/platform/tests/test-tc.c223
1 files changed, 223 insertions, 0 deletions
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);
+	}
+}