summaryrefslogtreecommitdiff
path: root/src/network/tc/sfq.c
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@vmware.com>2019-11-27 12:42:21 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-12-04 20:58:17 +0900
commit9942b71089aa0c71d67d876dbb9355891d222574 (patch)
treeb1a447262a440509020ce31b2dbf1d22eb1d6648 /src/network/tc/sfq.c
parent1b628c4f64e942c65a9703dbcb2f6e57c4818f55 (diff)
downloadsystemd-9942b71089aa0c71d67d876dbb9355891d222574.tar.gz
network: tc introduce sfq - Stochastic Fairness Queueing
Stochastic Fairness Queueing is a classless queueing discipline. SFQ does not shape traffic but only schedules the transmission of packets, based on 'flows'. The goal is to ensure fairness so that each flow is able to send data in turn, thus preventing any single flow from drowning out the rest.
Diffstat (limited to 'src/network/tc/sfq.c')
-rw-r--r--src/network/tc/sfq.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/network/tc/sfq.c b/src/network/tc/sfq.c
new file mode 100644
index 0000000000..393b0e12e1
--- /dev/null
+++ b/src/network/tc/sfq.c
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2019 VMware, Inc. */
+
+#include <linux/pkt_sched.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
+#include "netlink-util.h"
+#include "parse-util.h"
+#include "qdisc.h"
+#include "sfq.h"
+#include "string-util.h"
+
+int stochastic_fairness_queueing_new(StochasticFairnessQueueing **ret) {
+ StochasticFairnessQueueing *sfq = NULL;
+
+ sfq = new0(StochasticFairnessQueueing, 1);
+ if (!sfq)
+ return -ENOMEM;
+
+ *ret = TAKE_PTR(sfq);
+
+ return 0;
+}
+
+int stochastic_fairness_queueing_fill_message(Link *link, const StochasticFairnessQueueing *sfq, sd_netlink_message *req) {
+ struct tc_sfq_qopt_v1 opt = {};
+ int r;
+
+ assert(link);
+ assert(sfq);
+ assert(req);
+
+ opt.v0.perturb_period = sfq->perturb_period / USEC_PER_SEC;
+
+ r = sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(struct tc_sfq_qopt_v1));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append TCA_OPTIONS attribute: %m");
+
+ return 0;
+}
+
+int config_parse_tc_stochastic_fairness_queueing_perturb_period(
+ 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;
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = qdisc_new_static(network, filename, section_line, &qdisc);
+ if (r < 0)
+ return r;
+
+ if (isempty(rvalue)) {
+ qdisc->sfq.perturb_period = 0;
+
+ qdisc = NULL;
+ return 0;
+ }
+
+ r = parse_sec(rvalue, &qdisc->sfq.perturb_period);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse '%s=', ignoring assignment: %s",
+ lvalue, rvalue);
+ return 0;
+ }
+
+ qdisc->has_stochastic_fairness_queueing = true;
+ qdisc = NULL;
+
+ return 0;
+}