]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: tc: introduce DRR class
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Mar 2020 15:36:08 +0000 (00:36 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 12 Mar 2020 06:35:51 +0000 (15:35 +0900)
man/systemd.network.xml
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/tc/drr.c
src/network/tc/drr.h
src/network/tc/tclass.c
src/network/tc/tclass.h
test/fuzz/fuzz-network-parser/directives.network

index 556deea88178f380a7a55965b65992db8a6b7da6..516744c5f7159302c091ee707c513a2ae832c097 100644 (file)
     </variablelist>
   </refsect1>
 
+  <refsect1>
+    <title>[DeficitRoundRobinSchedulerClass] Section Options</title>
+    <para>The <literal>[DeficitRoundRobinSchedulerClass]</literal> section manages the traffic control class of
+    Deficit Round Robin Scheduler (DRR).</para>
+
+    <variablelist class='network-directives'>
+      <varlistentry>
+        <term><varname>Parent=</varname></term>
+        <listitem>
+          <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
+          <literal>clsact</literal>, <literal>ingress</literal> or a class id. The class id takes the
+          major and minor number in hexadecimal ranges 1 to ffff separated with a colon
+          (<literal>major:minor</literal>). Defaults to <literal>root</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>ClassId=</varname></term>
+        <listitem>
+          <para>Specifies the major and minur number of unique identifier of the class, known as the
+          class ID. Each number is in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>Quantum=</varname></term>
+        <listitem>
+          <para>Specifies the amount of bytes a flow is allowed to dequeue before the
+          scheduler moves to the next class. An unsigned integer ranges 1 to 4294967294.
+          Defaults to the MTU of the interface.</para>
+        </listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
   <refsect1>
     <title>[GenericRandomEarlyDetection] Section Options</title>
     <para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
index 17e4256b54b0c4cd99920805d2e5364a5121edbf..5d7150c58a29f2753f9c11e7c82b15b57f411143 100644 (file)
@@ -271,6 +271,9 @@ ControlledDelay.CEThresholdSec,              config_parse_controlled_delay_usec,
 ControlledDelay.ECN,                         config_parse_controlled_delay_bool,                       QDISC_KIND_CODEL,              0
 DeficitRoundRobinScheduler.Parent,           config_parse_qdisc_parent,                                QDISC_KIND_DRR,                0
 DeficitRoundRobinScheduler.Handle,           config_parse_qdisc_handle,                                QDISC_KIND_DRR,                0
+DeficitRoundRobinSchedulerClass.Parent,      config_parse_tclass_parent,                               TCLASS_KIND_DRR,               0
+DeficitRoundRobinSchedulerClass.ClassId,     config_parse_tclass_classid,                              TCLASS_KIND_DRR,               0
+DeficitRoundRobinSchedulerClass.Quantum,     config_parse_drr_size,                                    TCLASS_KIND_DRR,               0
 PFIFO.Parent,                                config_parse_qdisc_parent,                                QDISC_KIND_PFIFO,              0
 PFIFO.Handle,                                config_parse_qdisc_handle,                                QDISC_KIND_PFIFO,              0
 PFIFO.PacketLimit,                           config_parse_fifo_size,                                   QDISC_KIND_PFIFO,              0
index 896e5b9de6125d8c591b9edbc3d6b951fcb4b475..cf423e274a22fc3a6d8d34a69983b9ca377c2b88 100644 (file)
@@ -489,6 +489,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                               "CAKE\0"
                               "ControlledDelay\0"
                               "DeficitRoundRobinScheduler\0"
+                              "DeficitRoundRobinSchedulerClass\0"
                               "PFIFO\0"
                               "FairQueueing\0"
                               "FairQueueingControlledDelay\0"
index 086d775ed40ba4f0977f88df3c7e898acacdc5d1..ac64eb8b03e2d3e91d74f158463feb17c56c0606 100644 (file)
@@ -1,9 +1,105 @@
 /* SPDX-License-Identifier: LGPL-2.1+
  * Copyright © 2020 VMware, Inc. */
 
+#include <linux/pkt_sched.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
 #include "drr.h"
+#include "netlink-util.h"
+#include "parse-util.h"
+#include "string-util.h"
 
 const QDiscVTable drr_vtable = {
         .object_size = sizeof(DeficitRoundRobinScheduler),
         .tca_kind = "drr",
 };
+
+static int drr_class_fill_message(Link *link, TClass *tclass, sd_netlink_message *req) {
+        DeficitRoundRobinSchedulerClass *drr;
+        int r;
+
+        assert(link);
+        assert(tclass);
+        assert(req);
+
+        drr = TCLASS_TO_DRR(tclass);
+
+        r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "drr");
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
+
+        if (drr->quantum > 0) {
+                r = sd_netlink_message_append_u32(req, TCA_DRR_QUANTUM, drr->quantum);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append TCA_DRR_QUANTUM, attribute: %m");
+        }
+
+        r = sd_netlink_message_close_container(req);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
+
+        return 0;
+}
+
+int config_parse_drr_size(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
+        DeficitRoundRobinSchedulerClass *drr;
+        Network *network = data;
+        uint64_t u;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = tclass_new_static(TCLASS_KIND_DRR, network, filename, section_line, &tclass);
+        if (r < 0)
+                return log_syntax(unit, LOG_ERR, filename, line, r,
+                                  "Failed to create traffic control class, ignoring assignment: %m");
+
+        drr = TCLASS_TO_DRR(tclass);
+
+        if (isempty(rvalue)) {
+                drr->quantum = 0;
+
+                tclass = NULL;
+                return 0;
+        }
+
+        r = parse_size(rvalue, 1000, &u);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r,
+                           "Failed to parse '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+        if (u > UINT32_MAX) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+
+        drr->quantum = (uint32_t) u;
+
+        tclass = NULL;
+        return 0;
+}
+
+const TClassVTable drr_tclass_vtable = {
+        .object_size = sizeof(DeficitRoundRobinSchedulerClass),
+        .tca_kind = "drr",
+        .fill_message = drr_class_fill_message,
+};
index 4e20c4f7d1836a2d9b44de92412973cd1682ad5d..ff2b658acc97d5ab7d74a786ffe5da81a8fdfad7 100644 (file)
@@ -10,3 +10,14 @@ typedef struct DeficitRoundRobinScheduler {
 
 DEFINE_QDISC_CAST(DRR, DeficitRoundRobinScheduler);
 extern const QDiscVTable drr_vtable;
+
+typedef struct DeficitRoundRobinSchedulerClass {
+        TClass meta;
+
+        uint32_t quantum;
+} DeficitRoundRobinSchedulerClass;
+
+DEFINE_TCLASS_CAST(DRR, DeficitRoundRobinSchedulerClass);
+extern const TClassVTable drr_tclass_vtable;
+
+CONFIG_PARSER_PROTOTYPE(config_parse_drr_size);
index 87f5bcf70410df1dc6fe0319a0c6ded1e6a0a388..219ffa2ea6f7dd962fbb088d8add3df5d94c50a2 100644 (file)
@@ -16,6 +16,7 @@
 #include "tclass.h"
 
 const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
+        [TCLASS_KIND_DRR] = &drr_tclass_vtable,
         [TCLASS_KIND_HTB] = &htb_tclass_vtable,
 };
 
index 9698e582faadf90ac2bae6b56a441234f20b96a2..217dbfe001725ef3ec9b3085b156b3e4d995b14f 100644 (file)
@@ -9,6 +9,7 @@
 #include "tc.h"
 
 typedef enum TClassKind {
+        TCLASS_KIND_DRR,
         TCLASS_KIND_HTB,
         _TCLASS_KIND_MAX,
         _TCLASS_KIND_INVALID = -1,
@@ -64,4 +65,5 @@ DEFINE_TC_CAST(TCLASS, TClass);
 CONFIG_PARSER_PROTOTYPE(config_parse_tclass_parent);
 CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
 
+#include "drr.h"
 #include "htb.h"
index 151b1c2c39b8db6a624cee6cb9af7ff0f2bb05a7..6ea18d7dc96d1ec3121f0520f4933681ebd3812a 100644 (file)
@@ -377,3 +377,7 @@ PacketLimit=
 [DeficitRoundRobinScheduler]
 Parent=
 Handle=
+[DeficitRoundRobinSchedulerClass]
+Parent=
+ClassId=
+Quantum=