]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/tc/fq-codel.c
network: tc: rename several settings which take size in bytes
[thirdparty/systemd.git] / src / network / tc / fq-codel.c
CommitLineData
4e5ef149
SS
1/* SPDX-License-Identifier: LGPL-2.1+
2 * Copyright © 2019 VMware, Inc. */
3
4#include <linux/pkt_sched.h>
5
6#include "alloc-util.h"
7#include "conf-parser.h"
8#include "netlink-util.h"
9#include "parse-util.h"
10#include "qdisc.h"
11#include "string-util.h"
c03ef420 12#include "strv.h"
4e5ef149 13
18de0969
YW
14static int fair_queueing_controlled_delay_init(QDisc *qdisc) {
15 FairQueueingControlledDelay *fqcd;
ac810b75
YW
16
17 assert(qdisc);
18
19 fqcd = FQ_CODEL(qdisc);
20
21 fqcd->memory_limit = UINT32_MAX;
22 fqcd->ce_threshold_usec = USEC_INFINITY;
23 fqcd->ecn = -1;
24
25 return 0;
26}
27
18de0969
YW
28static int fair_queueing_controlled_delay_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
29 FairQueueingControlledDelay *fqcd;
4e5ef149
SS
30 int r;
31
32 assert(link);
e8c17dc0 33 assert(qdisc);
4e5ef149
SS
34 assert(req);
35
e8c17dc0
YW
36 fqcd = FQ_CODEL(qdisc);
37
92c7593f 38 r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "fq_codel");
4e5ef149
SS
39 if (r < 0)
40 return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
41
ac810b75
YW
42 if (fqcd->packet_limit > 0) {
43 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_LIMIT, fqcd->packet_limit);
44 if (r < 0)
45 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_LIMIT attribute: %m");
46 }
47
48 if (fqcd->flows > 0) {
49 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_FLOWS, fqcd->flows);
50 if (r < 0)
51 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_FLOWS attribute: %m");
52 }
53
54 if (fqcd->quantum > 0) {
55 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_QUANTUM, fqcd->quantum);
56 if (r < 0)
57 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_QUANTUM attribute: %m");
58 }
59
60 if (fqcd->interval_usec > 0) {
61 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_INTERVAL, fqcd->interval_usec);
62 if (r < 0)
63 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_INTERVAL attribute: %m");
64 }
65
66 if (fqcd->target_usec > 0) {
67 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_TARGET, fqcd->target_usec);
68 if (r < 0)
69 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_TARGET attribute: %m");
70 }
71
72 if (fqcd->ecn >= 0) {
73 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_ECN, fqcd->ecn);
74 if (r < 0)
75 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_ECN attribute: %m");
76 }
77
78 if (fqcd->ce_threshold_usec != USEC_INFINITY) {
79 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_CE_THRESHOLD, fqcd->ce_threshold_usec);
80 if (r < 0)
81 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_CE_THRESHOLD attribute: %m");
82 }
83
84 if (fqcd->memory_limit != UINT32_MAX) {
85 r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_MEMORY_LIMIT, fqcd->memory_limit);
86 if (r < 0)
87 return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_MEMORY_LIMIT attribute: %m");
88 }
4e5ef149
SS
89
90 r = sd_netlink_message_close_container(req);
91 if (r < 0)
92 return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
93
94 return 0;
95}
96
18de0969 97int config_parse_fair_queueing_controlled_delay_u32(
4e5ef149
SS
98 const char *unit,
99 const char *filename,
100 unsigned line,
101 const char *section,
102 unsigned section_line,
103 const char *lvalue,
104 int ltype,
105 const char *rvalue,
106 void *data,
107 void *userdata) {
108
109 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
18de0969 110 FairQueueingControlledDelay *fqcd;
4e5ef149 111 Network *network = data;
ac810b75 112 uint32_t *p;
4e5ef149
SS
113 int r;
114
115 assert(filename);
116 assert(lvalue);
117 assert(rvalue);
118 assert(data);
119
e8c17dc0
YW
120 r = qdisc_new_static(QDISC_KIND_FQ_CODEL, network, filename, section_line, &qdisc);
121 if (r == -ENOMEM)
122 return log_oom();
4e5ef149 123 if (r < 0)
e8c17dc0
YW
124 return log_syntax(unit, LOG_ERR, filename, line, r,
125 "More than one kind of queueing discipline, ignoring assignment: %m");
126
127 fqcd = FQ_CODEL(qdisc);
4e5ef149 128
18de0969 129 if (streq(lvalue, "PacketLimit"))
ac810b75 130 p = &fqcd->packet_limit;
18de0969 131 else if (streq(lvalue, "Flows"))
ac810b75
YW
132 p = &fqcd->flows;
133 else
134 assert_not_reached("Invalid lvalue.");
135
4e5ef149 136 if (isempty(rvalue)) {
ac810b75 137 *p = 0;
4e5ef149
SS
138
139 qdisc = NULL;
140 return 0;
141 }
142
ac810b75 143 r = safe_atou32(rvalue, p);
4e5ef149
SS
144 if (r < 0) {
145 log_syntax(unit, LOG_ERR, filename, line, r,
146 "Failed to parse '%s=', ignoring assignment: %s",
147 lvalue, rvalue);
148 return 0;
149 }
150
4e5ef149
SS
151 qdisc = NULL;
152
153 return 0;
154}
e8c17dc0 155
18de0969 156int config_parse_fair_queueing_controlled_delay_usec(
ac810b75
YW
157 const char *unit,
158 const char *filename,
159 unsigned line,
160 const char *section,
161 unsigned section_line,
162 const char *lvalue,
163 int ltype,
164 const char *rvalue,
165 void *data,
166 void *userdata) {
167
168 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
18de0969 169 FairQueueingControlledDelay *fqcd;
ac810b75
YW
170 Network *network = data;
171 usec_t *p;
172 int r;
173
174 assert(filename);
175 assert(lvalue);
176 assert(rvalue);
177 assert(data);
178
179 r = qdisc_new_static(QDISC_KIND_FQ_CODEL, network, filename, section_line, &qdisc);
180 if (r == -ENOMEM)
181 return log_oom();
182 if (r < 0)
183 return log_syntax(unit, LOG_ERR, filename, line, r,
184 "More than one kind of queueing discipline, ignoring assignment: %m");
185
186 fqcd = FQ_CODEL(qdisc);
187
18de0969 188 if (streq(lvalue, "TargetSec"))
ac810b75 189 p = &fqcd->target_usec;
18de0969 190 else if (streq(lvalue, "IntervalSec"))
ac810b75 191 p = &fqcd->interval_usec;
18de0969 192 else if (streq(lvalue, "CEThresholdSec"))
ac810b75
YW
193 p = &fqcd->ce_threshold_usec;
194 else
195 assert_not_reached("Invalid lvalue.");
196
197 if (isempty(rvalue)) {
18de0969 198 if (streq(lvalue, "CEThresholdSec"))
ac810b75
YW
199 *p = USEC_INFINITY;
200 else
201 *p = 0;
202
203 qdisc = NULL;
204 return 0;
205 }
206
207 r = parse_sec(rvalue, p);
208 if (r < 0) {
209 log_syntax(unit, LOG_ERR, filename, line, r,
210 "Failed to parse '%s=', ignoring assignment: %s",
211 lvalue, rvalue);
212 return 0;
213 }
214
215 qdisc = NULL;
216
217 return 0;
218}
219
18de0969 220int config_parse_fair_queueing_controlled_delay_bool(
ac810b75
YW
221 const char *unit,
222 const char *filename,
223 unsigned line,
224 const char *section,
225 unsigned section_line,
226 const char *lvalue,
227 int ltype,
228 const char *rvalue,
229 void *data,
230 void *userdata) {
231
232 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
18de0969 233 FairQueueingControlledDelay *fqcd;
ac810b75
YW
234 Network *network = data;
235 int r;
236
237 assert(filename);
238 assert(lvalue);
239 assert(rvalue);
240 assert(data);
241
242 r = qdisc_new_static(QDISC_KIND_FQ_CODEL, network, filename, section_line, &qdisc);
243 if (r == -ENOMEM)
244 return log_oom();
245 if (r < 0)
246 return log_syntax(unit, LOG_ERR, filename, line, r,
247 "More than one kind of queueing discipline, ignoring assignment: %m");
248
249 fqcd = FQ_CODEL(qdisc);
250
251 if (isempty(rvalue)) {
252 fqcd->ecn = -1;
253
254 qdisc = NULL;
255 return 0;
256 }
257
258 r = parse_boolean(rvalue);
259 if (r < 0) {
260 log_syntax(unit, LOG_ERR, filename, line, r,
261 "Failed to parse '%s=', ignoring assignment: %s",
262 lvalue, rvalue);
263 return 0;
264 }
265
266 fqcd->ecn = r;
267 qdisc = NULL;
268
269 return 0;
270}
271
18de0969 272int config_parse_fair_queueing_controlled_delay_size(
ac810b75
YW
273 const char *unit,
274 const char *filename,
275 unsigned line,
276 const char *section,
277 unsigned section_line,
278 const char *lvalue,
279 int ltype,
280 const char *rvalue,
281 void *data,
282 void *userdata) {
283
284 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
18de0969 285 FairQueueingControlledDelay *fqcd;
ac810b75
YW
286 Network *network = data;
287 uint64_t sz;
288 uint32_t *p;
289 int r;
290
291 assert(filename);
292 assert(lvalue);
293 assert(rvalue);
294 assert(data);
295
296 r = qdisc_new_static(QDISC_KIND_FQ_CODEL, network, filename, section_line, &qdisc);
297 if (r == -ENOMEM)
298 return log_oom();
299 if (r < 0)
300 return log_syntax(unit, LOG_ERR, filename, line, r,
301 "More than one kind of queueing discipline, ignoring assignment: %m");
302
303 fqcd = FQ_CODEL(qdisc);
304
c03ef420 305 if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
ac810b75 306 p = &fqcd->memory_limit;
c03ef420 307 else if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
ac810b75
YW
308 p = &fqcd->quantum;
309 else
310 assert_not_reached("Invalid lvalue.");
311
312 if (isempty(rvalue)) {
c03ef420 313 if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
ac810b75
YW
314 *p = UINT32_MAX;
315 else
316 *p = 0;
317
318 qdisc = NULL;
319 return 0;
320 }
321
322 r = parse_size(rvalue, 1024, &sz);
323 if (r < 0) {
324 log_syntax(unit, LOG_ERR, filename, line, r,
325 "Failed to parse '%s=', ignoring assignment: %s",
326 lvalue, rvalue);
327 return 0;
328 }
329 if (sz >= UINT32_MAX) {
330 log_syntax(unit, LOG_ERR, filename, line, r,
331 "Specified '%s=' is too large, ignoring assignment: %s",
332 lvalue, rvalue);
333 return 0;
334 }
335
336 *p = sz;
337 qdisc = NULL;
338
339 return 0;
340}
341
e8c17dc0 342const QDiscVTable fq_codel_vtable = {
18de0969 343 .object_size = sizeof(FairQueueingControlledDelay),
e8c17dc0 344 .tca_kind = "fq_codel",
18de0969
YW
345 .init = fair_queueing_controlled_delay_init,
346 .fill_message = fair_queueing_controlled_delay_fill_message,
e8c17dc0 347};