diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 3 | ||||
-rw-r--r-- | src/network/tc/netem.c | 17 | ||||
-rw-r--r-- | src/network/tc/netem.h | 3 | ||||
-rw-r--r-- | src/network/tc/qdisc.c | 19 |
4 files changed, 30 insertions, 12 deletions
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/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index ed4a11d265..7f4b2b53cb 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -116,6 +116,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int qdisc_configure(Link *link, QDiscs *qdisc) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + _cleanup_free_ char *tca_kind = NULL; int r; assert(link); @@ -132,25 +133,31 @@ int qdisc_configure(Link *link, QDiscs *qdisc) { return log_link_error_errno(link, r, "Could not create tcm_parent message: %m"); if (qdisc->parent == TC_H_CLSACT) { + tca_kind = strdup("clsact"); + if (!tca_kind) + return log_oom(); + r = sd_rtnl_message_set_qdisc_handle(req, TC_H_MAKE(TC_H_CLSACT, 0)); if (r < 0) return log_link_error_errno(link, r, "Could not set tcm_handle message: %m"); - - r = sd_netlink_message_append_string(req, TCA_KIND, "clsact"); - if (r < 0) - return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); } if (qdisc->has_network_emulator) { - r = sd_netlink_message_append_string(req, TCA_KIND, "netem"); + r = free_and_strdup(&tca_kind, "netem"); if (r < 0) - return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); + return log_oom(); r = network_emulator_fill_message(link, qdisc, req); if (r < 0) return r; } + if (tca_kind) { + r = sd_netlink_message_append_string(req, TCA_KIND, tca_kind); + if (r < 0) + return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); + } + r = netlink_call_async(link->manager->rtnl, NULL, req, qdisc_handler, link_netlink_destroy_callback, link); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); |