summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-05-25 15:17:09 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-05-28 17:25:31 +0200
commit53aa5bd2070f0edf6b7180b2ebef75e6d6c9d2a0 (patch)
treef42c954bba12b4dfa7507ded0ef4f00b8d564604
parent9064502834a650d8cb1a40f11b9833162679b109 (diff)
downloadNetworkManager-53aa5bd2070f0edf6b7180b2ebef75e6d6c9d2a0.tar.gz
platform: add tc tests
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am15
-rwxr-xr-xcontrib/fedora/REQUIRED_PACKAGES1
-rw-r--r--contrib/fedora/rpm/NetworkManager.spec4
-rw-r--r--src/platform/tests/meson.build2
-rw-r--r--src/platform/tests/test-common.c5
-rw-r--r--src/platform/tests/test-tc.c133
7 files changed, 162 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 78aca2baef..cfb77444e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -239,6 +239,8 @@ test-*.trs
/src/platform/tests/test-platform-general
/src/platform/tests/test-route-fake
/src/platform/tests/test-route-linux
+/src/platform/tests/test-tc-fake
+/src/platform/tests/test-tc-linux
/src/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.[ch]
/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh
/src/settings/plugins/ifupdown/tests/test-ifupdown
diff --git a/Makefile.am b/Makefile.am
index ae3f1fc006..f1a06dbf33 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3848,6 +3848,8 @@ check_programs += \
src/platform/tests/test-platform-general \
src/platform/tests/test-route-fake \
src/platform/tests/test-route-linux \
+ src/platform/tests/test-tc-fake \
+ src/platform/tests/test-tc-linux \
$(NULL)
src_platform_tests_monitor_CPPFLAGS = $(src_cppflags_test)
@@ -3902,6 +3904,17 @@ src_platform_tests_test_route_linux_CPPFLAGS = $(src_tests_cppflags_linux)
src_platform_tests_test_route_linux_LDFLAGS = $(src_platform_tests_ldflags)
src_platform_tests_test_route_linux_LDADD = $(src_platform_tests_libadd)
+src_platform_tests_test_tc_fake_SOURCES = src/platform/tests/test-tc.c
+src_platform_tests_test_tc_fake_CPPFLAGS = $(src_tests_cppflags_fake)
+src_platform_tests_test_tc_fake_LDFLAGS = $(src_platform_tests_ldflags)
+src_platform_tests_test_tc_fake_LDADD = $(src_platform_tests_libadd)
+
+src_platform_tests_test_tc_linux_SOURCES = src/platform/tests/test-tc.c
+src_platform_tests_test_tc_linux_CPPFLAGS = $(src_tests_cppflags_linux)
+src_platform_tests_test_tc_linux_LDFLAGS = $(src_platform_tests_ldflags)
+src_platform_tests_test_tc_linux_LDADD = $(src_platform_tests_libadd)
+
+
$(src_platform_tests_monitor_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_platform_tests_test_address_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_platform_tests_test_address_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
@@ -3913,6 +3926,8 @@ $(src_platform_tests_test_nmp_object_OBJECTS): $(libnm_core_lib_h_pub_mken
$(src_platform_tests_test_platform_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_platform_tests_test_route_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_platform_tests_test_route_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_platform_tests_test_tc_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_platform_tests_test_tc_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
EXTRA_DIST += \
src/platform/tests/meson.build \
diff --git a/contrib/fedora/REQUIRED_PACKAGES b/contrib/fedora/REQUIRED_PACKAGES
index f03eebfb00..18ba364199 100755
--- a/contrib/fedora/REQUIRED_PACKAGES
+++ b/contrib/fedora/REQUIRED_PACKAGES
@@ -86,6 +86,7 @@ install \
# some packages don't exist in certain distributions. Install them one-by-one, and ignore errors.
install_ignore_missing \
dbus-python \
+ iproute-tc \
libasan \
libpsl-devel \
libubsan \
diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec
index 59406e5b23..81567ab58a 100644
--- a/contrib/fedora/rpm/NetworkManager.spec
+++ b/contrib/fedora/rpm/NetworkManager.spec
@@ -250,6 +250,10 @@ BuildRequires: libubsan
%if %{with firewalld_zone}
BuildRequires: firewalld-filesystem
%endif
+BuildRequires: iproute
+%if 0%{?fedora} || 0%{?rhel} > 7
+BuildRequires: iproute-tc
+%endif
Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release}
diff --git a/src/platform/tests/meson.build b/src/platform/tests/meson.build
index 4a50bca978..f96850cc26 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 f28dfa3a72..9f6a29bc99 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-tc.c b/src/platform/tests/test-tc.c
new file mode 100644
index 0000000000..dc2bf9f214
--- /dev/null
+++ b/src/platform/tests/test-tc.c
@@ -0,0 +1,133 @@
+// 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_qdisc2 (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);
+}
+
+/*****************************************************************************/
+
+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/2", test_qdisc2, TRUE);
+ }
+}