From 2ed5f6d5de387dba1c739b776ffd35e9a1f8de77 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Feb 2020 19:10:33 +0900 Subject: [PATCH 1/7] network: introduce new [QDisc] section to support Parent=ingress Follow-up for 18de0969c5763ce119692b59f8622c379e79c6cc. --- man/systemd.network.xml | 15 +++++++++++++++ src/network/networkd-network-gperf.gperf | 3 ++- src/network/networkd-network.c | 1 + src/network/tc/qdisc.c | 1 - test/fuzz/fuzz-network-parser/directives.network | 2 ++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 793243f9ae..d8485f736f 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2270,6 +2270,21 @@ + + [QDisc] Section Options + The [QDisc] section manages the traffic control queueing discipline (qdisc). + + + + Parent= + + Specifies the parent Queueing Discipline (qdisc). Takes one of clsact + or ingress. This is mandatory. + + + + + [NetworkEmulator] Section Options The [NetworkEmulator] section manages the queueing discipline (qdisc) of diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 369631d9ee..81ce9ee1e4 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -251,6 +251,7 @@ CAN.BitRate, config_parse_si_uint64, CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point) CAN.RestartSec, config_parse_sec, 0, offsetof(Network, can_restart_us) CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling) +QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0 ControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_CODEL, 0 ControlledDelay.PacketLimit, config_parse_controlled_delay_u32, QDISC_KIND_CODEL, 0 ControlledDelay.TargetSec, config_parse_controlled_delay_usec, QDISC_KIND_CODEL, 0 @@ -320,7 +321,7 @@ DHCP.RapidCommit, config_parse_bool, DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains) DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) -TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0 +TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0 TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_network_emulator_delay, 0, 0 TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_network_emulator_delay, 0, 0 TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_network_emulator_rate, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 1b9e6a22b4..96f9c785ba 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -482,6 +482,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi "IPv6RoutePrefix\0" "TrafficControlQueueingDiscipline\0" "CAN\0" + "QDisc\0" "ControlledDelay\0" "FairQueueing\0" "FairQueueingControlledDelay\0" diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index ee0637bf32..c156fe5ce9 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -254,7 +254,6 @@ int config_parse_qdisc_parent( assert(lvalue); assert(rvalue); assert(data); - assert(ltype >= 0 && ltype < _QDISC_KIND_MAX); r = qdisc_new_static(ltype, network, filename, section_line, &qdisc); if (r < 0) diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 180a30c32c..5b04fefeb5 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -270,6 +270,8 @@ SendOption= [NextHop] Id= Gateway= +[QDisc] +Parent= [NetworkEmulator] Parent= DelaySec= From 4c2724013ffac93c5bc1956f374bfa85f3359ba9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Feb 2020 21:02:05 +0900 Subject: [PATCH 2/7] network: drop redundant %m --- src/network/tc/qdisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index c156fe5ce9..f8cf266fb3 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -138,7 +138,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { - log_link_message_error_errno(link, m, r, "Could not set QDisc: %m"); + log_link_message_error_errno(link, m, r, "Could not set QDisc"); link_enter_failed(link); return 1; } From ab119e633878ead1d6919d5ab366ad907f6dde02 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Feb 2020 21:09:03 +0900 Subject: [PATCH 3/7] network: append period if error message provided by kernel does not contain it --- src/network/networkd-link.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 7f37a8648b..c86cba8f8b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -4305,5 +4305,10 @@ int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, in const char *err_msg = NULL; (void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg); - return log_link_full(link, level, err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : ""); + return log_link_full(link, level, err, + "%s: %s%s%s%m", + msg, + strempty(err_msg), + err_msg && !endswith(err_msg, ".") ? "." : "", + err_msg ? " " : ""); } From 59bae425704fd5d3fe7c6fbdb1f58bd72551f55f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Feb 2020 21:12:34 +0900 Subject: [PATCH 4/7] network: update log message --- src/network/tc/qdisc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index f8cf266fb3..f1527cc1f5 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -218,15 +218,15 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact) { if (qdisc->parent == TC_H_ROOT) { if (*has_root) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: More than one root TrafficControlQueueingDiscipline sections are defined. " - "Ignoring [TrafficControlQueueingDiscipline] section from line %u.", + "%s: More than one root qdisc section is defined. " + "Ignoring the qdisc section from line %u.", qdisc->section->filename, qdisc->section->line); *has_root = true; } else if (qdisc->parent == TC_H_CLSACT) { /* TC_H_CLSACT == TC_H_INGRESS */ if (*has_clsact) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: More than one clsact or ingress TrafficControlQueueingDiscipline sections are defined. " - "Ignoring [TrafficControlQueueingDiscipline] section from line %u.", + "%s: More than one clsact or ingress qdisc section is defined. " + "Ignoring the qdisc section from line %u.", qdisc->section->filename, qdisc->section->line); *has_clsact = true; } From ab9dc1db477e4810c7da4548604b6a6b72388342 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Feb 2020 19:23:11 +0900 Subject: [PATCH 5/7] test-network: add more tests for traffic control --- .../conf/25-qdisc-clsact-root-compat.network | 12 +++++++++ .../25-qdisc-ingress-netem-compat.network | 16 +++++++++++ .../conf/25-qdisc-ingress-root.network | 12 +++++++++ test/test-network/systemd-networkd-tests.py | 27 +++++++++++++++++-- 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 test/test-network/conf/25-qdisc-clsact-root-compat.network create mode 100644 test/test-network/conf/25-qdisc-ingress-netem-compat.network create mode 100644 test/test-network/conf/25-qdisc-ingress-root.network diff --git a/test/test-network/conf/25-qdisc-clsact-root-compat.network b/test/test-network/conf/25-qdisc-clsact-root-compat.network new file mode 100644 index 0000000000..1f0dea46fb --- /dev/null +++ b/test/test-network/conf/25-qdisc-clsact-root-compat.network @@ -0,0 +1,12 @@ +[Match] +Name=dummy98 + +[Network] +IPv6AcceptRA=no +Address=10.1.2.3/16 + +#[TrafficControlQueueingDiscipline] +#Parent=root + +[TrafficControlQueueingDiscipline] +Parent=clsact diff --git a/test/test-network/conf/25-qdisc-ingress-netem-compat.network b/test/test-network/conf/25-qdisc-ingress-netem-compat.network new file mode 100644 index 0000000000..51dced2329 --- /dev/null +++ b/test/test-network/conf/25-qdisc-ingress-netem-compat.network @@ -0,0 +1,16 @@ +[Match] +Name=test1 + +[Network] +IPv6AcceptRA=no +Address=10.1.2.4/16 + +[TrafficControlQueueingDiscipline] +Parent=root +NetworkEmulatorDelaySec=50ms +NetworkEmulatorDelayJitterSec=10ms +NetworkEmulatorLossRate=20% +NetworkEmulatorPacketLimit=100 + +[TrafficControlQueueingDiscipline] +Parent=ingress diff --git a/test/test-network/conf/25-qdisc-ingress-root.network b/test/test-network/conf/25-qdisc-ingress-root.network new file mode 100644 index 0000000000..f72b70114b --- /dev/null +++ b/test/test-network/conf/25-qdisc-ingress-root.network @@ -0,0 +1,12 @@ +[Match] +Name=test1 + +[Network] +IPv6AcceptRA=no +Address=10.1.2.4/16 + +#[QDisc] +#Parent=root + +[QDisc] +Parent=ingress diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 454b00889d..423815c73a 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1616,7 +1616,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): '25-neighbor-ip-dummy.network', '25-neighbor-ip.network', '25-nexthop.network', + '25-qdisc-clsact-root-compat.network', '25-qdisc-fq-codel.network', + '25-qdisc-ingress-netem-compat.network', + '25-qdisc-ingress-root.network', '25-qdisc-netem-and-fqcodel.network', '25-qdisc-tbf-and-sfq.network', '25-route-ipv6-src.network', @@ -2248,10 +2251,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertRegex(output, 'perturb 5sec') def test_qdisc2(self): - copy_unit_to_networkd_unit_path('25-qdisc-fq-codel.network', '12-dummy.netdev') + copy_unit_to_networkd_unit_path('25-qdisc-fq-codel.network', '12-dummy.netdev', + '25-qdisc-ingress-root.network', '11-dummy.netdev') start_networkd() - self.wait_online(['dummy98:routable']) + self.wait_online(['dummy98:routable', 'test1:routable']) output = check_output('tc qdisc show dev dummy98') print(output) @@ -2262,6 +2266,25 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertRegex(output, 'maxrate 1Mbit') self.assertRegex(output, 'qdisc codel') self.assertRegex(output, 'limit 2000p target 10.0ms ce_threshold 100.0ms interval 50.0ms ecn') + output = check_output('tc qdisc show dev test1') + print(output) + self.assertRegex(output, 'qdisc ingress') + + def test_qdisc3(self): + copy_unit_to_networkd_unit_path('25-qdisc-clsact-root-compat.network', '12-dummy.netdev', + '25-qdisc-ingress-netem-compat.network', '11-dummy.netdev') + start_networkd() + + self.wait_online(['dummy98:routable', 'test1:routable']) + + output = check_output('tc qdisc show dev dummy98') + print(output) + self.assertRegex(output, 'qdisc clsact') + output = check_output('tc qdisc show dev test1') + print(output) + self.assertRegex(output, 'qdisc netem') + self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%') + self.assertRegex(output, 'qdisc ingress') class NetworkdStateFileTests(unittest.TestCase, Utilities): links = [ From 9b749c11e20bae3e70258dfdc217462003f73534 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Feb 2020 17:52:24 +0900 Subject: [PATCH 6/7] network: tc: support teql Closes #14792. --- man/systemd.network.xml | 25 ++++++ src/network/meson.build | 2 + src/network/networkd-network-gperf.gperf | 2 + src/network/networkd-network.c | 3 +- src/network/tc/qdisc.c | 21 +++-- src/network/tc/qdisc.h | 3 + src/network/tc/teql.c | 90 +++++++++++++++++++ src/network/tc/teql.h | 16 ++++ .../fuzz-network-parser/directives.network | 3 + 9 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/network/tc/teql.c create mode 100644 src/network/tc/teql.h diff --git a/man/systemd.network.xml b/man/systemd.network.xml index d8485f736f..6a2dd0d04c 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2677,6 +2677,31 @@ + + [TrivialLinkEqualizer] Section Options + The [TrivialLinkEqualizer] section manages the queueing discipline (qdisc) of + trivial link equalizer (teql). + + + + Parent= + + Specifies the parent Queueing Discipline (qdisc). Takes one of root, + clsact or ingress. Defaults to root. + + + + Id= + + Specifies the interface ID N of teql. Defaults to 0. + Note that when teql is used, currently, the module sch_teql with + max_equalizers=N+1 option must be loaded before + systemd-networkd is started. + + + + + [BridgeVLAN] Section Options The [BridgeVLAN] section manages the VLAN ID configuration of a bridge port and accepts diff --git a/src/network/meson.build b/src/network/meson.build index 7cb1bb5a38..c1c02cfda1 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -123,6 +123,8 @@ sources = files(''' tc/tbf.h tc/tc-util.c tc/tc-util.h + tc/teql.c + tc/teql.h '''.split()) systemd_networkd_sources = files('networkd.c') diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 81ce9ee1e4..3e2d8d8ee9 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -293,6 +293,8 @@ TokenBucketFilter.MTUBytes, config_parse_token_bucket_filter_si TokenBucketFilter.MPUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0 TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0 TokenBucketFilter.LatencySec, config_parse_token_bucket_filter_latency, QDISC_KIND_TBF, 0 +TrivialLinkEqualizer.Parent, config_parse_qdisc_parent, QDISC_KIND_TEQL, 0 +TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer_id, QDISC_KIND_TEQL, 0 /* backwards compatibility: do not add new entries to this section */ Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 96f9c785ba..b06ae75c05 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -488,7 +488,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi "FairQueueingControlledDelay\0" "NetworkEmulator\0" "StochasticFairnessQueueing\0" - "TokenBucketFilter\0", + "TokenBucketFilter\0" + "TrivialLinkEqualizer\0", config_item_perf_lookup, network_network_gperf_lookup, CONFIG_PARSE_WARN, network); if (r < 0) diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index f1527cc1f5..0d622c8aaf 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -20,6 +20,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { [QDISC_KIND_NETEM] = &netem_vtable, [QDISC_KIND_SFQ] = &sfq_vtable, [QDISC_KIND_TBF] = &tbf_vtable, + [QDISC_KIND_TEQL] = &teql_vtable, }; static int qdisc_new(QDiscKind kind, QDisc **ret) { @@ -176,13 +177,21 @@ int qdisc_configure(Link *link, QDisc *qdisc) { } if (QDISC_VTABLE(qdisc)) { - r = sd_netlink_message_append_string(req, TCA_KIND, QDISC_VTABLE(qdisc)->tca_kind); - if (r < 0) - return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); + if (QDISC_VTABLE(qdisc)->fill_tca_kind) { + r = QDISC_VTABLE(qdisc)->fill_tca_kind(link, qdisc, req); + if (r < 0) + return r; + } else { + r = sd_netlink_message_append_string(req, TCA_KIND, QDISC_VTABLE(qdisc)->tca_kind); + if (r < 0) + return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); + } - r = QDISC_VTABLE(qdisc)->fill_message(link, qdisc, req); - if (r < 0) - return r; + if (QDISC_VTABLE(qdisc)->fill_message) { + r = QDISC_VTABLE(qdisc)->fill_message(link, qdisc, req); + if (r < 0) + return r; + } } else { r = sd_netlink_message_append_string(req, TCA_KIND, qdisc->tca_kind); if (r < 0) diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h index bae4d1ab3f..b1753e4d95 100644 --- a/src/network/tc/qdisc.h +++ b/src/network/tc/qdisc.h @@ -14,6 +14,7 @@ typedef enum QDiscKind { QDISC_KIND_NETEM, QDISC_KIND_SFQ, QDISC_KIND_TBF, + QDISC_KIND_TEQL, _QDISC_KIND_MAX, _QDISC_KIND_INVALID = -1, } QDiscKind; @@ -35,6 +36,7 @@ typedef struct QDiscVTable { const char *tca_kind; /* called in qdisc_new() */ int (*init)(QDisc *qdisc); + int (*fill_tca_kind)(Link *link, QDisc *qdisc, sd_netlink_message *m); int (*fill_message)(Link *link, QDisc *qdisc, sd_netlink_message *m); int (*verify)(QDisc *qdisc); } QDiscVTable; @@ -71,3 +73,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent); #include "netem.h" #include "sfq.h" #include "tbf.h" +#include "teql.h" diff --git a/src/network/tc/teql.c b/src/network/tc/teql.c new file mode 100644 index 0000000000..aac9499616 --- /dev/null +++ b/src/network/tc/teql.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "macro.h" +#include "netlink-util.h" +#include "parse-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "teql.h" + +static int trivial_link_equalizer_fill_tca_kind(Link *link, QDisc *qdisc, sd_netlink_message *req) { + char kind[STRLEN("teql") + DECIMAL_STR_MAX(unsigned)]; + TrivialLinkEqualizer *teql; + int r; + + assert(link); + assert(qdisc); + assert(req); + + teql = TEQL(qdisc); + + xsprintf(kind, "teql%u", teql->id); + r = sd_netlink_message_append_string(req, TCA_KIND, kind); + if (r < 0) + return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); + + return 0; +} + +const QDiscVTable teql_vtable = { + .object_size = sizeof(TrivialLinkEqualizer), + .fill_tca_kind = trivial_link_equalizer_fill_tca_kind, +}; + +int config_parse_trivial_link_equalizer_id( + 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; + TrivialLinkEqualizer *teql; + Network *network = data; + unsigned id; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = qdisc_new_static(QDISC_KIND_TEQL, network, filename, section_line, &qdisc); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_syntax(unit, LOG_ERR, filename, line, r, + "More than one kind of queueing discipline, ignoring assignment: %m"); + + teql = TEQL(qdisc); + + if (isempty(rvalue)) { + teql->id = 0; + + qdisc = NULL; + return 0; + } + + r = safe_atou(rvalue, &id); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse '%s=', ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + if (id > INT_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "'%s=' is too large, ignoring assignment: %s", + lvalue, rvalue); + } + + teql->id = id; + + qdisc = NULL; + return 0; +} diff --git a/src/network/tc/teql.h b/src/network/tc/teql.h new file mode 100644 index 0000000000..5b091aaf0f --- /dev/null +++ b/src/network/tc/teql.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "conf-parser.h" +#include "qdisc.h" + +typedef struct TrivialLinkEqualizer { + QDisc meta; + + unsigned id; +} TrivialLinkEqualizer; + +DEFINE_QDISC_CAST(TEQL, TrivialLinkEqualizer); +extern const QDiscVTable teql_vtable; + +CONFIG_PARSER_PROTOTYPE(config_parse_trivial_link_equalizer_id); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 5b04fefeb5..cfee5db02f 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -326,3 +326,6 @@ NetworkEmulatorDelayJitterSec= NetworkEmulatorLossRate= NetworkEmulatorDuplicateRate= NetworkEmulatorPacketLimit= +[TrivialLinkEqualizer] +Parent= +Id= From 3d55b5a9def5e39a548afa957475af21134cb4bf Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Feb 2020 17:53:04 +0900 Subject: [PATCH 7/7] test-network: add test for teql --- test/test-network/conf/25-qdisc-teql.network | 10 ++++++++++ test/test-network/systemd-networkd-tests.py | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 test/test-network/conf/25-qdisc-teql.network diff --git a/test/test-network/conf/25-qdisc-teql.network b/test/test-network/conf/25-qdisc-teql.network new file mode 100644 index 0000000000..e506bb17a2 --- /dev/null +++ b/test/test-network/conf/25-qdisc-teql.network @@ -0,0 +1,10 @@ +[Match] +Name=dummy98 + +[Network] +IPv6AcceptRA=no +Address=10.1.2.3/16 + +[TrivialLinkEqualizer] +Parent=root +Id=1 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 423815c73a..b62160bf59 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1622,6 +1622,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): '25-qdisc-ingress-root.network', '25-qdisc-netem-and-fqcodel.network', '25-qdisc-tbf-and-sfq.network', + '25-qdisc-teql.network', '25-route-ipv6-src.network', '25-route-static.network', '25-gateway-static.network', @@ -2286,6 +2287,17 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%') self.assertRegex(output, 'qdisc ingress') + def test_qdisc4(self): + copy_unit_to_networkd_unit_path('25-qdisc-teql.network', '12-dummy.netdev') + check_output('modprobe sch_teql max_equalizers=2') + start_networkd() + + self.wait_online(['dummy98:routable']) + + output = check_output('tc qdisc show dev dummy98') + print(output) + self.assertRegex(output, 'qdisc teql1') + class NetworkdStateFileTests(unittest.TestCase, Utilities): links = [ 'dummy98',