/src/systemd/src/network/tc/sfb.c
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later |
2 | | * Copyright © 2020 VMware, Inc. */ |
3 | | |
4 | | #include <linux/pkt_sched.h> |
5 | | #include "sd-netlink.h" |
6 | | |
7 | | #include "log.h" |
8 | | #include "parse-util.h" |
9 | | #include "qdisc.h" |
10 | | #include "sfb.h" |
11 | | #include "string-util.h" |
12 | | |
13 | 0 | static int stochastic_fair_blue_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) { |
14 | 0 | StochasticFairBlue *sfb; |
15 | 0 | int r; |
16 | |
|
17 | 0 | assert(link); |
18 | 0 | assert(qdisc); |
19 | 0 | assert(req); |
20 | |
|
21 | 0 | assert_se(sfb = SFB(qdisc)); |
22 | |
|
23 | 0 | const struct tc_sfb_qopt opt = { |
24 | 0 | .rehash_interval = 600*1000, |
25 | 0 | .warmup_time = 60*1000, |
26 | 0 | .penalty_rate = 10, |
27 | 0 | .penalty_burst = 20, |
28 | 0 | .increment = (SFB_MAX_PROB + 1000) / 2000, |
29 | 0 | .decrement = (SFB_MAX_PROB + 10000) / 20000, |
30 | 0 | .max = 25, |
31 | 0 | .bin_size = 20, |
32 | 0 | .limit = sfb->packet_limit, |
33 | 0 | }; |
34 | |
|
35 | 0 | r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "sfb"); |
36 | 0 | if (r < 0) |
37 | 0 | return r; |
38 | | |
39 | 0 | r = sd_netlink_message_append_data(req, TCA_SFB_PARMS, &opt, sizeof(opt)); |
40 | 0 | if (r < 0) |
41 | 0 | return r; |
42 | | |
43 | 0 | r = sd_netlink_message_close_container(req); |
44 | 0 | if (r < 0) |
45 | 0 | return r; |
46 | | |
47 | 0 | return 0; |
48 | 0 | } |
49 | | |
50 | | int config_parse_sfb_u32( |
51 | | const char *unit, |
52 | | const char *filename, |
53 | | unsigned line, |
54 | | const char *section, |
55 | | unsigned section_line, |
56 | | const char *lvalue, |
57 | | int ltype, |
58 | | const char *rvalue, |
59 | | void *data, |
60 | 590 | void *userdata) { |
61 | | |
62 | 590 | _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; |
63 | 590 | StochasticFairBlue *sfb; |
64 | 590 | Network *network = ASSERT_PTR(data); |
65 | 590 | int r; |
66 | | |
67 | 590 | assert(filename); |
68 | 590 | assert(lvalue); |
69 | 590 | assert(rvalue); |
70 | | |
71 | 590 | r = qdisc_new_static(QDISC_KIND_SFB, network, filename, section_line, &qdisc); |
72 | 590 | if (r == -ENOMEM) |
73 | 0 | return log_oom(); |
74 | 590 | if (r < 0) { |
75 | 0 | log_syntax(unit, LOG_WARNING, filename, line, r, |
76 | 0 | "More than one kind of queueing discipline, ignoring assignment: %m"); |
77 | 0 | return 0; |
78 | 0 | } |
79 | | |
80 | 590 | sfb = SFB(qdisc); |
81 | | |
82 | 590 | if (isempty(rvalue)) { |
83 | 194 | sfb->packet_limit = 0; |
84 | | |
85 | 194 | TAKE_PTR(qdisc); |
86 | 194 | return 0; |
87 | 194 | } |
88 | | |
89 | 396 | r = safe_atou32(rvalue, &sfb->packet_limit); |
90 | 396 | if (r < 0) { |
91 | 202 | log_syntax(unit, LOG_WARNING, filename, line, r, |
92 | 202 | "Failed to parse '%s=', ignoring assignment: %s", |
93 | 202 | lvalue, rvalue); |
94 | 202 | return 0; |
95 | 202 | } |
96 | | |
97 | 194 | TAKE_PTR(qdisc); |
98 | | |
99 | 194 | return 0; |
100 | 396 | } |
101 | | |
102 | | const QDiscVTable sfb_vtable = { |
103 | | .object_size = sizeof(StochasticFairBlue), |
104 | | .tca_kind = "sfb", |
105 | | .fill_message = stochastic_fair_blue_fill_message, |
106 | | }; |