]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: tc/cake: introduce CompensationMode= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Nov 2021 19:50:00 +0000 (04:50 +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 4ace6d60d8dc3fba079cda6e63d3a718893ef7ee..9a8d13d6c59a148a424c5f95f5d254d9b2e41130 100644 (file)
@@ -3491,6 +3491,18 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>CompensationMode=</varname></term>
+        <listitem>
+          <para>Takes one of <literal>none</literal>, <literal>atm</literal>, or <literal>ptm</literal>.
+          Specifies the compensation mode for overhead calculation. When <literal>none</literal>, no
+          compensation is taken into account. When <literal>atm</literal>, enables the compensation for
+          ATM cell framing, which is normally found on ADSL links. When <literal>ptm</literal>, enables
+          the compensation for PTM encoding, which is normally found on VDSL2 links and uses a 64b/65b
+          encoding scheme. Defaults to unset and the kernel's default is used.</para>
+        </listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index c34b3e1812293f14bb9384f2ea6bc1d0c2aba5b0..2d0e1f833fbd8d3df03547a5d5915c04b5ee6377 100644 (file)
@@ -388,6 +388,7 @@ CAKE.Handle,                                 config_parse_qdisc_handle,
 CAKE.Bandwidth,                              config_parse_cake_bandwidth,                              QDISC_KIND_CAKE,               0
 CAKE.AutoRateIngress,                        config_parse_cake_tristate,                               QDISC_KIND_CAKE,               0
 CAKE.OverheadBytes,                          config_parse_cake_overhead,                               QDISC_KIND_CAKE,               0
+CAKE.CompensationMode,                       config_parse_cake_compensation_mode,                      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 813a679bf717b3739fcd12acc0a2a1e4b9cc6a4d..fe007c00fdbf0c8dfa072c6bbff53df27e9d79af 100644 (file)
@@ -9,6 +9,7 @@
 #include "netlink-util.h"
 #include "parse-util.h"
 #include "qdisc.h"
+#include "string-table.h"
 #include "string-util.h"
 
 static int cake_init(QDisc *qdisc) {
@@ -19,6 +20,7 @@ static int cake_init(QDisc *qdisc) {
         c = CAKE(qdisc);
 
         c->autorate = -1;
+        c->compensation_mode = _CAKE_COMPENSATION_MODE_INVALID;
 
         return 0;
 }
@@ -55,6 +57,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_OVERHEAD attribute: %m");
         }
 
+        if (c->compensation_mode >= 0) {
+                r = sd_netlink_message_append_u32(req, TCA_CAKE_ATM, c->compensation_mode);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append TCA_CAKE_ATM 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");
@@ -234,6 +242,67 @@ int config_parse_cake_tristate(
         return 0;
 }
 
+static const char * const cake_compensation_mode_table[_CAKE_COMPENSATION_MODE_MAX] = {
+        [CAKE_COMPENSATION_MODE_NONE] = "none",
+        [CAKE_COMPENSATION_MODE_ATM]  = "atm",
+        [CAKE_COMPENSATION_MODE_PTM]  = "ptm",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(cake_compensation_mode, CakeCompensationMode);
+
+int config_parse_cake_compensation_mode(
+                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;
+        Network *network = data;
+        CakeCompensationMode mode;
+        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->compensation_mode = _CAKE_COMPENSATION_MODE_INVALID;
+                TAKE_PTR(qdisc);
+                return 0;
+        }
+
+        mode = cake_compensation_mode_from_string(rvalue);
+        if (mode < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, mode,
+                           "Failed to parse '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+
+        c->compensation_mode = mode;
+        TAKE_PTR(qdisc);
+        return 0;
+}
+
 const QDiscVTable cake_vtable = {
         .object_size = sizeof(CommonApplicationsKeptEnhanced),
         .tca_kind = "cake",
index 08fa3c266b547679bcd41bde59f228fe11595f19..549b4e3c808ffd2e0e63bfb4599859093c3fbb46 100644 (file)
@@ -2,9 +2,19 @@
  * Copyright © 2020 VMware, Inc. */
 #pragma once
 
+#include <linux/pkt_sched.h>
+
 #include "conf-parser.h"
 #include "qdisc.h"
 
+typedef enum CakeCompensationMode {
+        CAKE_COMPENSATION_MODE_NONE = CAKE_ATM_NONE,
+        CAKE_COMPENSATION_MODE_ATM  = CAKE_ATM_ATM,
+        CAKE_COMPENSATION_MODE_PTM  = CAKE_ATM_PTM,
+        _CAKE_COMPENSATION_MODE_MAX,
+        _CAKE_COMPENSATION_MODE_INVALID = -EINVAL,
+} CakeCompensationMode;
+
 typedef struct CommonApplicationsKeptEnhanced {
         QDisc meta;
 
@@ -15,6 +25,7 @@ typedef struct CommonApplicationsKeptEnhanced {
         /* Overhead compensation parameters */
         bool overhead_set;
         int overhead;
+        CakeCompensationMode compensation_mode;
 
 } CommonApplicationsKeptEnhanced;
 
@@ -24,3 +35,4 @@ extern const QDiscVTable cake_vtable;
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_bandwidth);
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_overhead);
 CONFIG_PARSER_PROTOTYPE(config_parse_cake_tristate);
+CONFIG_PARSER_PROTOTYPE(config_parse_cake_compensation_mode);
index 83e9fa9054d165dafbd7a3d0504fb50f37dfc1b9..79ca97c90b0c597ef32b6449e1ba0e50cd5dc6c7 100644 (file)
@@ -470,6 +470,7 @@ Handle=
 Bandwidth=
 AutoRateIngress=
 OverheadBytes=
+CompensationMode=
 [TrafficControlQueueingDiscipline]
 Parent=
 NetworkEmulatorDelaySec=