]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: tc/cake: introduce PriorityQueueingProfile= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 3 Nov 2021 19:59:37 +0000 (04:59 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Nov 2021 01:58:44 +0000 (10:58 +0900)
man/systemd.network.xml
src/network/networkd-network-gperf.gperf
src/network/tc/cake.c
src/network/tc/cake.h
test/fuzz/fuzz-network-parser/directives.network

index b82efd4394ca5846097f2aa50365b7c90e841a89..31fa8d31ff088c9a384323e90bac66230af2af01 100644 (file)
@@ -3607,6 +3607,59 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>PriorityQueueingPreset=</varname></term>
+        <listitem>
+          <para>CAKE divides traffic into <literal>tins</literal>, and each tin has its own independent
+          set of flow-isolation queues, bandwidth threshold, and priority. This specifies the preset of
+          tin profiles. The available values are:</para>
+
+          <variablelist>
+            <varlistentry>
+              <term><option>besteffort</option></term>
+              <listitem><para>
+                Disables priority queueing by placing all traffic in one tin.
+              </para></listitem>
+            </varlistentry>
+            <varlistentry>
+              <term><option>precedence</option></term>
+              <listitem><para>
+                Enables priority queueing based on the legacy interpretation of TOS
+                <literal>Precedence</literal> field. Use of this preset on the modern Internet is
+                firmly discouraged.
+              </para></listitem>
+            </varlistentry>
+            <varlistentry>
+              <term><option>diffserv8</option></term>
+              <listitem><para>
+                Enables priority queueing based on the Differentiated Service
+                (<literal>DiffServ</literal>) field with eight tins: Background Traffic, High
+                Throughput, Best Effort, Video Streaming, Low Latency Transactions, Interactive Shell,
+                Minimum Latency, and Network Control.
+              </para></listitem>
+            </varlistentry>
+            <varlistentry>
+              <term><option>diffserv4</option></term>
+              <listitem><para>
+                Enables priority queueing based on the Differentiated Service
+                (<literal>DiffServ</literal>) field with four tins: Background Traffic, Best Effort,
+                Streaming Media, and Latency Sensitive.
+              </para></listitem>
+            </varlistentry>
+            <varlistentry>
+              <term><option>diffserv3</option></term>
+              <listitem><para>
+                Enables priority queueing based on the Differentiated Service
+                (<literal>DiffServ</literal>) field with three tins: Background Traffic, Best Effort,
+                and Latency Sensitive.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+
+          <para>Defaults to unset, and the kernel's default is used.</para>
+        </listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 1c09f300bd63fd2e0dbe973811ef961fe36a12e0..0404f911230d50a2dff9228e0a624752c95d2a64 100644 (file)
@@ -392,6 +392,7 @@ CAKE.MPUBytes,                               config_parse_cake_mpu,
 CAKE.CompensationMode,                       config_parse_cake_compensation_mode,                      QDISC_KIND_CAKE,               0
 CAKE.FlowIsolationMode,                      config_parse_cake_flow_isolation_mode,                    QDISC_KIND_CAKE,               0
 CAKE.NAT,                                    config_parse_cake_tristate,                               QDISC_KIND_CAKE,               0
+CAKE.PriorityQueueingPreset,                 config_parse_cake_priority_queueing_preset,               QDISC_KIND_CAKE,               0
 ControlledDelay.Parent,                      config_parse_qdisc_parent,                                QDISC_KIND_CODEL,              0
 ControlledDelay.Handle,                      config_parse_qdisc_handle,                                QDISC_KIND_CODEL,              0
 ControlledDelay.PacketLimit,                 config_parse_controlled_delay_u32,                        QDISC_KIND_CODEL,              0
index 7641574fd8f9e0b5c14e97080f8f181fdba6c8fc..cd03f8feac7e2e8b74fa7b272fd71f928a5e7006 100644 (file)
@@ -23,6 +23,7 @@ static int cake_init(QDisc *qdisc) {
         c->compensation_mode = _CAKE_COMPENSATION_MODE_INVALID;
         c->flow_isolation_mode = _CAKE_FLOW_ISOLATION_MODE_INVALID;
         c->nat = -1;
+        c->preset = _CAKE_PRESET_INVALID;
 
         return 0;
 }
@@ -83,6 +84,12 @@ static int cake_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req)
                         return log_link_error_errno(link, r, "Could not append TCA_CAKE_NAT attribute: %m");
         }
 
+        if (c->preset >= 0) {
+                r = sd_netlink_message_append_u32(req, TCA_CAKE_DIFFSERV_MODE, c->preset);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append TCA_CAKE_DIFFSERV_MODE 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");
@@ -450,6 +457,69 @@ int config_parse_cake_flow_isolation_mode(
         return 0;
 }
 
+static const char * const cake_priority_queueing_preset_table[_CAKE_PRESET_MAX] = {
+        [CAKE_PRESET_DIFFSERV3]  = "diffserv3",
+        [CAKE_PRESET_DIFFSERV4]  = "diffserv4",
+        [CAKE_PRESET_DIFFSERV8]  = "diffserv8",
+        [CAKE_PRESET_BESTEFFORT] = "besteffort",
+        [CAKE_PRESET_PRECEDENCE] = "precedence",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(cake_priority_queueing_preset, CakePriorityQueueingPreset);
+
+int config_parse_cake_priority_queueing_preset(
+                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_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
+        CommonApplicationsKeptEnhanced *c;
+        CakePriorityQueueingPreset preset;
+        Network *network = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = qdisc_new_static(QDISC_KIND_CAKE, network, filename, section_line, &qdisc);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "More than one kind of queueing discipline, ignoring assignment: %m");
+                return 0;
+        }
+
+        c = CAKE(qdisc);
+
+        if (isempty(rvalue)) {
+                c->preset = _CAKE_PRESET_INVALID;
+                TAKE_PTR(qdisc);
+                return 0;
+        }
+
+        preset = cake_priority_queueing_preset_from_string(rvalue);
+        if (preset < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, preset,
+                           "Failed to parse '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+
+        c->preset = preset;
+        TAKE_PTR(qdisc);
+        return 0;
+}
+
 const QDiscVTable cake_vtable = {
         .object_size = sizeof(CommonApplicationsKeptEnhanced),
         .tca_kind = "cake",
index c8defb505eb71f90e712715a357260e858b44ff3..a14cb6b80660e8dc3234bc38d03b2fb207fd77ff 100644 (file)
@@ -28,6 +28,16 @@ typedef enum CakeFlowIsolationMode {
         _CAKE_FLOW_ISOLATION_MODE_INVALID = -EINVAL,
 } CakeFlowIsolationMode;
 
+typedef enum CakePriorityQueueingPreset {
+        CAKE_PRESET_DIFFSERV3  = CAKE_DIFFSERV_DIFFSERV3,
+        CAKE_PRESET_DIFFSERV4  = CAKE_DIFFSERV_DIFFSERV4,
+        CAKE_PRESET_DIFFSERV8  = CAKE_DIFFSERV_DIFFSERV8,
+        CAKE_PRESET_BESTEFFORT = CAKE_DIFFSERV_BESTEFFORT,
+        CAKE_PRESET_PRECEDENCE = CAKE_DIFFSERV_PRECEDENCE,
+        _CAKE_PRESET_MAX,
+        _CAKE_PRESET_INVALID = -EINVAL,
+} CakePriorityQueueingPreset;
+
 typedef struct CommonApplicationsKeptEnhanced {
         QDisc meta;
 
@@ -45,6 +55,9 @@ typedef struct CommonApplicationsKeptEnhanced {
         CakeFlowIsolationMode flow_isolation_mode;
         int nat;
 
+        /* Priority queue parameters */
+        CakePriorityQueueingPreset preset;
+
 } CommonApplicationsKeptEnhanced;
 
 DEFINE_QDISC_CAST(CAKE, CommonApplicationsKeptEnhanced);
@@ -56,3 +69,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_cake_mpu);
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_tristate);
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_compensation_mode);
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_flow_isolation_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_cake_priority_queueing_preset);
index de6d460eb1f1ed680b067524214ef6eb1d621b75..e4734af87943e913fc2df6665c8d7371f387cd4f 100644 (file)
@@ -474,6 +474,7 @@ MPUBytes=
 CompensationMode=
 FlowIsolationMode=
 NAT=
+PriorityQueueingPreset=
 [TrafficControlQueueingDiscipline]
 Parent=
 NetworkEmulatorDelaySec=