From b9c5aa3c65b5f223f79aaa0db549c0aaf2aeee25 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 30 Oct 2019 18:58:02 +0100 Subject: [PATCH] qdisc: netem add support to duplicate packets. using this option the chosen percent of packets is duplicated before queuing them --- man/systemd.network.xml | 8 ++++++++ src/network/networkd-network-gperf.gperf | 3 ++- src/network/tc/netem.c | 17 +++++++++++++---- src/network/tc/netem.h | 3 ++- .../fuzz/fuzz-network-parser/directives.network | 1 + 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 0d49bf9589..fb2f199ba8 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2351,6 +2351,14 @@ + + NetworkEmulatorDuplicateRate= + + Specifies that the chosen percent of packets is duplicated before queuing them. + Takes a percentage value, suffixed with "%". Defaults to unset. + + + diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 9f53385602..7fca93dccb 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -247,7 +247,8 @@ CAN.TripleSampling, config_parse_tristate, TrafficControlQueueingDiscipline.Parent, config_parse_tc_qdiscs_parent, 0, 0 TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_tc_network_emulator_delay, 0, 0 TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_tc_network_emulator_delay, 0, 0 -TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_loss_rate, 0, 0 +TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_rate, 0, 0 +TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_tc_network_emulator_rate, 0, 0 TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_tc_network_emulator_packet_limit, 0, 0 /* backwards compatibility: do not add new entries to this section */ Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) diff --git a/src/network/tc/netem.c b/src/network/tc/netem.c index e0e3e9a48e..053af3e7db 100644 --- a/src/network/tc/netem.c +++ b/src/network/tc/netem.c @@ -50,6 +50,9 @@ int network_emulator_fill_message(Link *link, QDiscs *qdisc, sd_netlink_message if (qdisc->ne.loss > 0) opt.loss = qdisc->ne.loss; + if (qdisc->ne.duplicate > 0) + opt.duplicate = qdisc->ne.duplicate; + if (qdisc->ne.delay != USEC_INFINITY) { r = tc_time_to_tick(qdisc->ne.delay, &opt.latency); if (r < 0) @@ -124,7 +127,7 @@ int config_parse_tc_network_emulator_delay( return 0; } -int config_parse_tc_network_emulator_loss_rate( +int config_parse_tc_network_emulator_rate( const char *unit, const char *filename, unsigned line, @@ -138,6 +141,7 @@ int config_parse_tc_network_emulator_loss_rate( _cleanup_(qdisc_free_or_set_invalidp) QDiscs *qdisc = NULL; Network *network = data; + uint32_t rate; int r; assert(filename); @@ -156,14 +160,19 @@ int config_parse_tc_network_emulator_loss_rate( return 0; } - r = parse_tc_percent(rvalue, &qdisc->ne.loss); + r = parse_tc_percent(rvalue, &rate); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse 'NetworkEmularorLossRate=', ignoring assignment: %s", - rvalue); + "Failed to parse '%s=', ignoring assignment: %s", + lvalue, rvalue); return 0; } + if (streq(lvalue, "NetworkEmulatorLossRate")) + qdisc->ne.loss = rate; + else if (streq(lvalue, "NetworkEmulatorDuplicateRate")) + qdisc->ne.duplicate = rate; + qdisc = NULL; return 0; } diff --git a/src/network/tc/netem.h b/src/network/tc/netem.h index 4bac44ca5a..43abf20af8 100644 --- a/src/network/tc/netem.h +++ b/src/network/tc/netem.h @@ -16,11 +16,12 @@ typedef struct NetworkEmulator { uint32_t limit; uint32_t loss; + uint32_t duplicate; } NetworkEmulator; int network_emulator_new(NetworkEmulator **ret); int network_emulator_fill_message(Link *link, QDiscs *qdisc, sd_netlink_message *req); CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_delay); -CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_loss_rate); +CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_rate); CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_packet_limit); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 3469dd443e..a5f54610da 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -268,4 +268,5 @@ Parent= NetworkEmulatorDelaySec= NetworkEmulatorDelayJitterSec= NetworkEmulatorLossRate= +NetworkEmulatorDuplicateRate= NetworkEmulatorPacketLimit=