From: Yu Watanabe Date: Tue, 2 Nov 2021 19:50:00 +0000 (+0900) Subject: network: tc/cake: introduce CompensationMode= setting X-Git-Tag: v250-rc1~330^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b6eccfda1ae5fb1e5db61a2d642666f9b70a2b59;p=thirdparty%2Fsystemd.git network: tc/cake: introduce CompensationMode= setting --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 4ace6d60d8d..9a8d13d6c59 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -3491,6 +3491,18 @@ Token=prefixstable:2002:da8:1:: + + CompensationMode= + + Takes one of none, atm, or ptm. + Specifies the compensation mode for overhead calculation. When none, no + compensation is taken into account. When atm, enables the compensation for + ATM cell framing, which is normally found on ADSL links. When ptm, 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. + + + diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c34b3e18122..2d0e1f833fb 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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 diff --git a/src/network/tc/cake.c b/src/network/tc/cake.c index 813a679bf71..fe007c00fdb 100644 --- a/src/network/tc/cake.c +++ b/src/network/tc/cake.c @@ -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", diff --git a/src/network/tc/cake.h b/src/network/tc/cake.h index 08fa3c266b5..549b4e3c808 100644 --- a/src/network/tc/cake.h +++ b/src/network/tc/cake.h @@ -2,9 +2,19 @@ * Copyright © 2020 VMware, Inc. */ #pragma once +#include + #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); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 83e9fa9054d..79ca97c90b0 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -470,6 +470,7 @@ Handle= Bandwidth= AutoRateIngress= OverheadBytes= +CompensationMode= [TrafficControlQueueingDiscipline] Parent= NetworkEmulatorDelaySec=