about summary refs log tree commit diff
path: root/src/core/platform/tests/test-tc.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /src/core/platform/tests/test-tc.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/core/platform/tests/test-tc.c')
-rw-r--r--src/core/platform/tests/test-tc.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/src/core/platform/tests/test-tc.c b/src/core/platform/tests/test-tc.c
new file mode 100644
index 00000000..d15c3d76
--- /dev/null
+++ b/src/core/platform/tests/test-tc.c
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "src/core/nm-default-daemon.h"
+
+#include <linux/pkt_sched.h>
+
+#include "nm-test-utils-core.h"
+#include "platform/nmp-object.h"
+#include "nm-platform/nmp-netns.h"
+#include "nm-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);
+    }
+}