From 15d25fa2870068fc1dd34629e6efeb2fb3cbb565 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Sep 12 2024 14:38:58 +0000 Subject: Backport support for multiq qdisc #34251 --- diff --git a/34251.patch b/34251.patch new file mode 100644 index 0000000..30dc0f9 --- /dev/null +++ b/34251.patch @@ -0,0 +1,373 @@ +From 3f14557ce01cc9012991a602851b03f0a4205fc2 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 4 Sep 2024 12:19:49 +0200 +Subject: [PATCH 1/2] network: Add support for multiq qdisc + +--- + man/systemd.network.xml | 10 ++++++++++ + src/network/meson.build | 1 + + src/network/networkd-network-gperf.gperf | 2 ++ + src/network/networkd-network.c | 1 + + src/network/tc/multiq.c | 19 +++++++++++++++++++ + src/network/tc/multiq.h | 11 +++++++++++ + src/network/tc/qdisc.c | 1 + + src/network/tc/qdisc.h | 2 ++ + .../test-network/conf/25-qdisc-multiq.network | 12 ++++++++++++ + test/test-network/systemd-networkd-tests.py | 10 ++++++++++ + 10 files changed, 69 insertions(+) + create mode 100644 src/network/tc/multiq.c + create mode 100644 src/network/tc/multiq.h + create mode 100644 test/test-network/conf/25-qdisc-multiq.network + +diff --git a/man/systemd.network.xml b/man/systemd.network.xml +index 734a4f7c0b21b..cc6a31484f20c 100644 +--- a/man/systemd.network.xml ++++ b/man/systemd.network.xml +@@ -6064,6 +6064,16 @@ ServerAddress=192.168.0.1/24 + + + ++ ++ [BandMultiQueueing] Section Options ++ The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq). ++ ++ ++ ++ ++ ++ ++ + + [HeavyHitterFilter] Section Options + The [HeavyHitterFilter] section manages the queueing discipline (qdisc) of Heavy Hitter Filter +diff --git a/src/network/meson.build b/src/network/meson.build +index 275542daa27f5..3edcd48c83e63 100644 +--- a/src/network/meson.build ++++ b/src/network/meson.build +@@ -93,6 +93,7 @@ sources = files( + 'tc/gred.c', + 'tc/hhf.c', + 'tc/htb.c', ++ 'tc/multiq.c', + 'tc/netem.c', + 'tc/pie.c', + 'tc/qdisc.c', +diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf +index 0957eeef6ed8b..95fe0275a9be4 100644 +--- a/src/network/networkd-network-gperf.gperf ++++ b/src/network/networkd-network-gperf.gperf +@@ -552,6 +552,8 @@ HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket + HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0 + HierarchyTokenBucketClass.BufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 + HierarchyTokenBucketClass.CeilBufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 ++BandMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MULTIQ, 0 ++BandMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MULTIQ, 0 + NetworkEmulator.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0 + NetworkEmulator.Handle, config_parse_qdisc_handle, QDISC_KIND_NETEM, 0 + NetworkEmulator.DelaySec, config_parse_network_emulator_delay, QDISC_KIND_NETEM, 0 +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c +index ecd54a3829d49..2c2f8ad939064 100644 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -551,6 +551,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi + "HeavyHitterFilter\0" + "HierarchyTokenBucket\0" + "HierarchyTokenBucketClass\0" ++ "BandMultiQueueing\0" + "NetworkEmulator\0" + "PFIFO\0" + "PFIFOFast\0" +diff --git a/src/network/tc/multiq.c b/src/network/tc/multiq.c +new file mode 100644 +index 0000000000000..c70d8c59061e3 +--- /dev/null ++++ b/src/network/tc/multiq.c +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++ ++#include "multiq.h" ++ ++static int multi_queueing_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) { ++ struct tc_multiq_qopt opt = {}; ++ ++ assert(req); ++ ++ /* It looks weird, but the multiq qdisc initialization wants to receive a tc_multiq_qopt attr even ++ * though it doesn't do anything with it. */ ++ return sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(opt)); ++} ++ ++const QDiscVTable multiq_vtable = { ++ .object_size = sizeof(BandMultiQueueing), ++ .tca_kind = "multiq", ++ .fill_message = multi_queueing_fill_message, ++}; +diff --git a/src/network/tc/multiq.h b/src/network/tc/multiq.h +new file mode 100644 +index 0000000000000..e53ed57c716ab +--- /dev/null ++++ b/src/network/tc/multiq.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++#pragma once ++ ++#include "qdisc.h" ++ ++typedef struct BandMultiQueueing { ++ QDisc meta; ++} BandMultiQueueing; ++ ++DEFINE_QDISC_CAST(MULTIQ, BandMultiQueueing); ++extern const QDiscVTable multiq_vtable; +diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c +index 0f89d844f585a..5e8f97a785100 100644 +--- a/src/network/tc/qdisc.c ++++ b/src/network/tc/qdisc.c +@@ -30,6 +30,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { + [QDISC_KIND_GRED] = &gred_vtable, + [QDISC_KIND_HHF] = &hhf_vtable, + [QDISC_KIND_HTB] = &htb_vtable, ++ [QDISC_KIND_MULTIQ] = &multiq_vtable, + [QDISC_KIND_NETEM] = &netem_vtable, + [QDISC_KIND_PIE] = &pie_vtable, + [QDISC_KIND_QFQ] = &qfq_vtable, +diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h +index 50a8f4ead1951..83853dcaa742c 100644 +--- a/src/network/tc/qdisc.h ++++ b/src/network/tc/qdisc.h +@@ -21,6 +21,7 @@ typedef enum QDiscKind { + QDISC_KIND_GRED, + QDISC_KIND_HHF, + QDISC_KIND_HTB, ++ QDISC_KIND_MULTIQ, + QDISC_KIND_NETEM, + QDISC_KIND_PFIFO, + QDISC_KIND_PFIFO_FAST, +@@ -106,6 +107,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle); + #include "gred.h" + #include "hhf.h" + #include "htb.h" ++#include "multiq.h" + #include "pie.h" + #include "qfq.h" + #include "netem.h" +diff --git a/test/test-network/conf/25-qdisc-multiq.network b/test/test-network/conf/25-qdisc-multiq.network +new file mode 100644 +index 0000000000000..a805c77124d0c +--- /dev/null ++++ b/test/test-network/conf/25-qdisc-multiq.network +@@ -0,0 +1,12 @@ ++# SPDX-License-Identifier: LGPL-2.1-or-later ++[Match] ++Name=testtun99 ++Name=testtap99 ++ ++[Network] ++LinkLocalAddressing=yes ++IPv6AcceptRA=no ++ ++[BandMultiQueueing] ++Parent=root ++Handle=0002 +diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py +index 1b61038d09e08..a2b4eb40b239d 100755 +--- a/test/test-network/systemd-networkd-tests.py ++++ b/test/test-network/systemd-networkd-tests.py +@@ -4648,6 +4648,16 @@ def test_qdisc_ingress(self): + print(output) + self.assertRegex(output, 'qdisc ingress') + ++ @expectedFailureIfModuleIsNotAvailable('sch_multiq') ++ def test_qdisc_multiq(self): ++ copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-multiq.network') ++ start_networkd() ++ self.wait_online('testtun99:degraded', 'testtap99:degraded') ++ ++ output = check_output('tc qdisc show dev testtun99') ++ print(output) ++ self.assertIn('qdisc multiq 2: root', output) ++ + @expectedFailureIfModuleIsNotAvailable('sch_netem') + def test_qdisc_netem(self): + copy_network_unit('25-qdisc-netem.network', '12-dummy.netdev', + +From 2b9ced9072a280a2cb0c2c7783a288788a3a6771 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 4 Sep 2024 13:32:32 +0200 +Subject: [PATCH 2/2] network: Add support for mq qdisc + +--- + man/systemd.network.xml | 10 ++++++++++ + src/network/meson.build | 1 + + src/network/networkd-network-gperf.gperf | 2 ++ + src/network/networkd-network.c | 1 + + src/network/tc/mq.c | 8 ++++++++ + src/network/tc/mq.h | 11 +++++++++++ + src/network/tc/qdisc.c | 1 + + src/network/tc/qdisc.h | 2 ++ + test/test-network/conf/25-qdisc-mq.network | 12 ++++++++++++ + test/test-network/systemd-networkd-tests.py | 9 +++++++++ + 10 files changed, 57 insertions(+) + create mode 100644 src/network/tc/mq.c + create mode 100644 src/network/tc/mq.h + create mode 100644 test/test-network/conf/25-qdisc-mq.network + +diff --git a/man/systemd.network.xml b/man/systemd.network.xml +index cc6a31484f20c..89484c449f31d 100644 +--- a/man/systemd.network.xml ++++ b/man/systemd.network.xml +@@ -6064,6 +6064,16 @@ ServerAddress=192.168.0.1/24 + + + ++ ++ [ClassfulMultiQueueing] Section Options ++ The [ClassfulMultiQueueing] section manages the queueing discipline (qdisc) of Classful Multi Queueing (mq). ++ ++ ++ ++ ++ ++ ++ + + [BandMultiQueueing] Section Options + The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq). +diff --git a/src/network/meson.build b/src/network/meson.build +index 3edcd48c83e63..54cf694aeb47e 100644 +--- a/src/network/meson.build ++++ b/src/network/meson.build +@@ -93,6 +93,7 @@ sources = files( + 'tc/gred.c', + 'tc/hhf.c', + 'tc/htb.c', ++ 'tc/mq.c', + 'tc/multiq.c', + 'tc/netem.c', + 'tc/pie.c', +diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf +index 95fe0275a9be4..a84de4ca7fca9 100644 +--- a/src/network/networkd-network-gperf.gperf ++++ b/src/network/networkd-network-gperf.gperf +@@ -552,6 +552,8 @@ HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket + HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0 + HierarchyTokenBucketClass.BufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 + HierarchyTokenBucketClass.CeilBufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 ++ClassfulMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MQ, 0 ++ClassfulMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MQ, 0 + BandMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MULTIQ, 0 + BandMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MULTIQ, 0 + NetworkEmulator.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0 +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c +index 2c2f8ad939064..8ccf215a71e84 100644 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -551,6 +551,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi + "HeavyHitterFilter\0" + "HierarchyTokenBucket\0" + "HierarchyTokenBucketClass\0" ++ "ClassfulMultiQueueing\0" + "BandMultiQueueing\0" + "NetworkEmulator\0" + "PFIFO\0" +diff --git a/src/network/tc/mq.c b/src/network/tc/mq.c +new file mode 100644 +index 0000000000000..1435ed1fda0fa +--- /dev/null ++++ b/src/network/tc/mq.c +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++ ++#include "mq.h" ++ ++const QDiscVTable mq_vtable = { ++ .object_size = sizeof(ClassfulMultiQueueing), ++ .tca_kind = "mq", ++}; +diff --git a/src/network/tc/mq.h b/src/network/tc/mq.h +new file mode 100644 +index 0000000000000..88f0049670cf1 +--- /dev/null ++++ b/src/network/tc/mq.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++#pragma once ++ ++#include "qdisc.h" ++ ++typedef struct ClassfulMultiQueueing { ++ QDisc meta; ++} ClassfulMultiQueueing; ++ ++DEFINE_QDISC_CAST(MQ, ClassfulMultiQueueing); ++extern const QDiscVTable mq_vtable; +diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c +index 5e8f97a785100..3bcc3930662f4 100644 +--- a/src/network/tc/qdisc.c ++++ b/src/network/tc/qdisc.c +@@ -30,6 +30,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { + [QDISC_KIND_GRED] = &gred_vtable, + [QDISC_KIND_HHF] = &hhf_vtable, + [QDISC_KIND_HTB] = &htb_vtable, ++ [QDISC_KIND_MQ] = &mq_vtable, + [QDISC_KIND_MULTIQ] = &multiq_vtable, + [QDISC_KIND_NETEM] = &netem_vtable, + [QDISC_KIND_PIE] = &pie_vtable, +diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h +index 83853dcaa742c..80b95c2aab4fc 100644 +--- a/src/network/tc/qdisc.h ++++ b/src/network/tc/qdisc.h +@@ -21,6 +21,7 @@ typedef enum QDiscKind { + QDISC_KIND_GRED, + QDISC_KIND_HHF, + QDISC_KIND_HTB, ++ QDISC_KIND_MQ, + QDISC_KIND_MULTIQ, + QDISC_KIND_NETEM, + QDISC_KIND_PFIFO, +@@ -107,6 +108,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle); + #include "gred.h" + #include "hhf.h" + #include "htb.h" ++#include "mq.h" + #include "multiq.h" + #include "pie.h" + #include "qfq.h" +diff --git a/test/test-network/conf/25-qdisc-mq.network b/test/test-network/conf/25-qdisc-mq.network +new file mode 100644 +index 0000000000000..32366d05dabed +--- /dev/null ++++ b/test/test-network/conf/25-qdisc-mq.network +@@ -0,0 +1,12 @@ ++# SPDX-License-Identifier: LGPL-2.1-or-later ++[Match] ++Name=testtun99 ++Name=testtap99 ++ ++[Network] ++LinkLocalAddressing=yes ++IPv6AcceptRA=no ++ ++[ClassfulMultiQueueing] ++Parent=root ++Handle=0002 +diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py +index a2b4eb40b239d..3989fc04014d1 100755 +--- a/test/test-network/systemd-networkd-tests.py ++++ b/test/test-network/systemd-networkd-tests.py +@@ -4648,6 +4648,15 @@ def test_qdisc_ingress(self): + print(output) + self.assertRegex(output, 'qdisc ingress') + ++ def test_qdisc_mq(self): ++ copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-mq.network') ++ start_networkd() ++ self.wait_online('testtun99:degraded', 'testtap99:degraded') ++ ++ output = check_output('tc qdisc show dev testtun99') ++ print(output) ++ self.assertIn('qdisc mq 2: root', output) ++ + @expectedFailureIfModuleIsNotAvailable('sch_multiq') + def test_qdisc_multiq(self): + copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-multiq.network') diff --git a/systemd.spec b/systemd.spec index 1b5208c..10ef7ce 100644 --- a/systemd.spec +++ b/systemd.spec @@ -123,6 +123,9 @@ Patch0491: https://github.com/systemd/systemd/pull/30846.patch # Soft-disable tmpfiles --purge until a good use case comes up. Patch0492: 0001-tmpfiles-make-purge-hard-to-mis-use.patch +# network: Add support for multiq qdisc +Patch0493: https://github.com/systemd/systemd/pull/34251.patch + %ifarch %{ix86} x86_64 aarch64 riscv64 %global want_bootloader 1 %endif