network: tc/cake: introduce AutoRateIngress= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Nov 2021 19:05:02 +0000 (04:05 +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 39acb2a6a9c45498213977032daf15805f958a9e..4ace6d60d8dc3fba079cda6e63d3a718893ef7ee 100644 (file)
@@ -3472,6 +3472,16 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>AutoRateIngress=</varname></term>
+        <listitem>
+          <para>Takes a boolean value. Enables automatic capacity estimation based on traffic arriving
+          at this qdisc. This is most likely to be useful with cellular links, which tend to change
+          quality randomly. If this setting is enabled, the <varname>Bandwidth=</varname> setting is
+          used as an initial estimate. Defaults to unset, and the kernel's default is used.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>OverheadBytes=</varname></term>
         <listitem>
index 1f0a625183bb2b68d719f368f3c35a0279d1490e..c34b3e1812293f14bb9384f2ea6bc1d0c2aba5b0 100644 (file)
@@ -386,6 +386,7 @@ BFIFO.LimitBytes,                            config_parse_bfifo_size,
 CAKE.Parent,                                 config_parse_qdisc_parent,                                QDISC_KIND_CAKE,               0
 CAKE.Handle,                                 config_parse_qdisc_handle,                                QDISC_KIND_CAKE,               0
 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
 ControlledDelay.Parent,                      config_parse_qdisc_parent,                                QDISC_KIND_CODEL,              0
 ControlledDelay.Handle,                      config_parse_qdisc_handle,                                QDISC_KIND_CODEL,              0
index 70dd095e932732ac023fba6157b2c125a647f685..0f77036fd808f3c072d9f24b9a10b93571246ef7 100644 (file)
 #include "qdisc.h"
 #include "string-util.h"
 
+static int cake_init(QDisc *qdisc) {
+        CommonApplicationsKeptEnhanced *c;
+
+        assert(qdisc);
+
+        c = CAKE(qdisc);
+
+        c->autorate = -1;
+
+        return 0;
+}
+
 static int cake_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
         CommonApplicationsKeptEnhanced *c;
         int r;
@@ -31,6 +43,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_BASE_RATE64 attribute: %m");
         }
 
+        if (c->autorate >= 0) {
+                r = sd_netlink_message_append_u32(req, TCA_CAKE_AUTORATE, c->autorate);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append TCA_CAKE_AUTORATE attribute: %m");
+        }
+
         r = sd_netlink_message_append_s32(req, TCA_CAKE_OVERHEAD, c->overhead);
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not append TCA_CAKE_OVERHEAD attribute: %m");
@@ -156,8 +174,66 @@ int config_parse_cake_overhead(
         return 0;
 }
 
+int config_parse_cake_tristate(
+                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;
+        int *dest, 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 (streq(lvalue, "AutoRateIngress"))
+                dest = &c->autorate;
+        else
+                assert_not_reached();
+
+        if (isempty(rvalue)) {
+                *dest = -1;
+                TAKE_PTR(qdisc);
+                return 0;
+        }
+
+        r = parse_boolean(rvalue);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse '%s=', ignoring assignment: %s",
+                           lvalue, rvalue);
+                return 0;
+        }
+
+        *dest = r;
+        TAKE_PTR(qdisc);
+        return 0;
+}
+
 const QDiscVTable cake_vtable = {
         .object_size = sizeof(CommonApplicationsKeptEnhanced),
         .tca_kind = "cake",
+        .init = cake_init,
         .fill_message = cake_fill_message,
 };
index 1da28b7d203929e4ec6ee4bff0e557a615a41594..ba9dcb9a08011da9708458d3c18934787e422915 100644 (file)
@@ -8,9 +8,13 @@
 typedef struct CommonApplicationsKeptEnhanced {
         QDisc meta;
 
-        int overhead;
+        /* Shaper parameters */
+        int autorate;
         uint64_t bandwidth;
 
+        /* Overhead compensation parameters */
+        int overhead;
+
 } CommonApplicationsKeptEnhanced;
 
 DEFINE_QDISC_CAST(CAKE, CommonApplicationsKeptEnhanced);
@@ -18,3 +22,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);
index 2ff20e0f083789e6bdc4b186ed760062f6d01534..83e9fa9054d165dafbd7a3d0504fb50f37dfc1b9 100644 (file)
@@ -468,6 +468,7 @@ ECN=
 Parent=
 Handle=
 Bandwidth=
+AutoRateIngress=
 OverheadBytes=
 [TrafficControlQueueingDiscipline]
 Parent=