]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/tc/fq.c
network: downgrade log level in conf parsers
[thirdparty/systemd.git] / src / network / tc / fq.c
CommitLineData
7234b915
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 "fq.h"
9#include "netlink-util.h"
10#include "parse-util.h"
11#include "string-util.h"
c03ef420 12#include "strv.h"
e83562e5 13
949fb07e 14static int fair_queueing_init(QDisc *qdisc) {
ca58d00c 15 FairQueueing *fq;
e83562e5
YW
16
17 assert(qdisc);
18
19 fq = FQ(qdisc);
20
21 fq->pacing = -1;
22 fq->ce_threshold_usec = USEC_INFINITY;
23
24 return 0;
25}
7234b915 26
949fb07e 27static int fair_queueing_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
ca58d00c 28 FairQueueing *fq;
7234b915
SS
29 int r;
30
31 assert(link);
32 assert(qdisc);
33 assert(req);
34
35 fq = FQ(qdisc);
36
37 r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "fq");
38 if (r < 0)
39 return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
40
e83562e5
YW
41 if (fq->packet_limit > 0) {
42 r = sd_netlink_message_append_u32(req, TCA_FQ_PLIMIT, fq->packet_limit);
43 if (r < 0)
44 return log_link_error_errno(link, r, "Could not append TCA_FQ_PLIMIT attribute: %m");
45 }
46
47 if (fq->flow_limit > 0) {
48 r = sd_netlink_message_append_u32(req, TCA_FQ_FLOW_PLIMIT, fq->flow_limit);
49 if (r < 0)
50 return log_link_error_errno(link, r, "Could not append TCA_FQ_FLOW_PLIMIT attribute: %m");
51 }
52
53 if (fq->quantum > 0) {
54 r = sd_netlink_message_append_u32(req, TCA_FQ_QUANTUM, fq->quantum);
55 if (r < 0)
56 return log_link_error_errno(link, r, "Could not append TCA_FQ_QUANTUM attribute: %m");
57 }
58
59 if (fq->initial_quantum > 0) {
60 r = sd_netlink_message_append_u32(req, TCA_FQ_INITIAL_QUANTUM, fq->initial_quantum);
61 if (r < 0)
62 return log_link_error_errno(link, r, "Could not append TCA_FQ_INITIAL_QUANTUM attribute: %m");
63 }
64
65 if (fq->pacing >= 0) {
66 r = sd_netlink_message_append_u32(req, TCA_FQ_RATE_ENABLE, fq->pacing);
67 if (r < 0)
68 return log_link_error_errno(link, r, "Could not append TCA_FQ_RATE_ENABLE attribute: %m");
69 }
70
71 if (fq->max_rate > 0) {
72 r = sd_netlink_message_append_u32(req, TCA_FQ_FLOW_MAX_RATE, fq->max_rate);
73 if (r < 0)
74 return log_link_error_errno(link, r, "Could not append TCA_FQ_FLOW_MAX_RATE attribute: %m");
75 }
76
77 if (fq->buckets > 0) {
78 uint32_t l;
79
80 l = log2u(fq->buckets);
81 r = sd_netlink_message_append_u32(req, TCA_FQ_BUCKETS_LOG, l);
82 if (r < 0)
83 return log_link_error_errno(link, r, "Could not append TCA_FQ_BUCKETS_LOG attribute: %m");
84 }
85
86 if (fq->orphan_mask > 0) {
87 r = sd_netlink_message_append_u32(req, TCA_FQ_ORPHAN_MASK, fq->orphan_mask);
88 if (r < 0)
89 return log_link_error_errno(link, r, "Could not append TCA_FQ_ORPHAN_MASK attribute: %m");
90 }
91
92 if (fq->ce_threshold_usec != USEC_INFINITY) {
93 r = sd_netlink_message_append_u32(req, TCA_FQ_CE_THRESHOLD, fq->ce_threshold_usec);
94 if (r < 0)
95 return log_link_error_errno(link, r, "Could not append TCA_FQ_CE_THRESHOLD attribute: %m");
96 }
7234b915
SS
97
98 r = sd_netlink_message_close_container(req);
99 if (r < 0)
100 return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
101
102 return 0;
103}
104
949fb07e 105int config_parse_fair_queueing_u32(
7234b915
SS
106 const char *unit,
107 const char *filename,
108 unsigned line,
109 const char *section,
110 unsigned section_line,
111 const char *lvalue,
112 int ltype,
113 const char *rvalue,
114 void *data,
115 void *userdata) {
116
117 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
ca58d00c 118 FairQueueing *fq;
7234b915 119 Network *network = data;
e83562e5 120 uint32_t *p;
7234b915
SS
121 int r;
122
123 assert(filename);
124 assert(lvalue);
125 assert(rvalue);
126 assert(data);
127
128 r = qdisc_new_static(QDISC_KIND_FQ, network, filename, section_line, &qdisc);
129 if (r == -ENOMEM)
130 return log_oom();
d96edb2c
YW
131 if (r < 0) {
132 log_syntax(unit, LOG_WARNING, filename, line, r,
133 "More than one kind of queueing discipline, ignoring assignment: %m");
134 return 0;
135 }
7234b915
SS
136
137 fq = FQ(qdisc);
138
18de0969 139 if (streq(lvalue, "PacketLimit"))
e83562e5 140 p = &fq->packet_limit;
18de0969 141 else if (streq(lvalue, "FlowLimit"))
e83562e5 142 p = &fq->flow_limit;
18de0969 143 else if (streq(lvalue, "Buckets"))
e83562e5 144 p = &fq->buckets;
18de0969 145 else if (streq(lvalue, "OrphanMask"))
e83562e5
YW
146 p = &fq->orphan_mask;
147 else
148 assert_not_reached("Invalid lvalue");
149
7234b915 150 if (isempty(rvalue)) {
e83562e5 151 *p = 0;
7234b915
SS
152
153 qdisc = NULL;
154 return 0;
155 }
156
e83562e5 157 r = safe_atou32(rvalue, p);
7234b915 158 if (r < 0) {
d96edb2c 159 log_syntax(unit, LOG_WARNING, filename, line, r,
7234b915
SS
160 "Failed to parse '%s=', ignoring assignment: %s",
161 lvalue, rvalue);
162 return 0;
163 }
164
165 qdisc = NULL;
166
167 return 0;
168}
169
949fb07e 170int config_parse_fair_queueing_size(
e83562e5
YW
171 const char *unit,
172 const char *filename,
173 unsigned line,
174 const char *section,
175 unsigned section_line,
176 const char *lvalue,
177 int ltype,
178 const char *rvalue,
179 void *data,
180 void *userdata) {
181
182 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
ca58d00c 183 FairQueueing *fq;
e83562e5
YW
184 Network *network = data;
185 uint64_t sz;
186 uint32_t *p;
187 int r;
188
189 assert(filename);
190 assert(lvalue);
191 assert(rvalue);
192 assert(data);
193
194 r = qdisc_new_static(QDISC_KIND_FQ, network, filename, section_line, &qdisc);
195 if (r == -ENOMEM)
196 return log_oom();
d96edb2c
YW
197 if (r < 0) {
198 log_syntax(unit, LOG_WARNING, filename, line, r,
199 "More than one kind of queueing discipline, ignoring assignment: %m");
200 return 0;
201 }
e83562e5
YW
202
203 fq = FQ(qdisc);
204
c03ef420 205 if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
e83562e5 206 p = &fq->quantum;
c03ef420 207 else if (STR_IN_SET(lvalue, "InitialQuantumBytes", "InitialQuantum"))
e83562e5
YW
208 p = &fq->initial_quantum;
209 else
210 assert_not_reached("Invalid lvalue");
211
212 if (isempty(rvalue)) {
213 *p = 0;
214
215 qdisc = NULL;
216 return 0;
217 }
218
219 r = parse_size(rvalue, 1024, &sz);
220 if (r < 0) {
d96edb2c 221 log_syntax(unit, LOG_WARNING, filename, line, r,
e83562e5
YW
222 "Failed to parse '%s=', ignoring assignment: %s",
223 lvalue, rvalue);
224 return 0;
225 }
226 if (sz > UINT32_MAX) {
d96edb2c 227 log_syntax(unit, LOG_WARNING, filename, line, 0,
e83562e5
YW
228 "Specified '%s=' is too large, ignoring assignment: %s",
229 lvalue, rvalue);
230 return 0;
231 }
232
233 *p = sz;
234 qdisc = NULL;
235
236 return 0;
237}
238
949fb07e 239int config_parse_fair_queueing_bool(
e83562e5
YW
240 const char *unit,
241 const char *filename,
242 unsigned line,
243 const char *section,
244 unsigned section_line,
245 const char *lvalue,
246 int ltype,
247 const char *rvalue,
248 void *data,
249 void *userdata) {
250
251 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
ca58d00c 252 FairQueueing *fq;
e83562e5
YW
253 Network *network = data;
254 int r;
255
256 assert(filename);
257 assert(lvalue);
258 assert(rvalue);
259 assert(data);
260
261 r = qdisc_new_static(QDISC_KIND_FQ, network, filename, section_line, &qdisc);
262 if (r == -ENOMEM)
263 return log_oom();
d96edb2c
YW
264 if (r < 0) {
265 log_syntax(unit, LOG_WARNING, filename, line, r,
266 "More than one kind of queueing discipline, ignoring assignment: %m");
267 return 0;
268 }
e83562e5
YW
269
270 fq = FQ(qdisc);
271
272 if (isempty(rvalue)) {
273 fq->pacing = -1;
274
275 qdisc = NULL;
276 return 0;
277 }
278
279 r = parse_boolean(rvalue);
280 if (r < 0) {
d96edb2c 281 log_syntax(unit, LOG_WARNING, filename, line, r,
e83562e5
YW
282 "Failed to parse '%s=', ignoring assignment: %s",
283 lvalue, rvalue);
284 return 0;
285 }
286
287 fq->pacing = r;
288 qdisc = NULL;
289
290 return 0;
291}
292
949fb07e 293int config_parse_fair_queueing_usec(
e83562e5
YW
294 const char *unit,
295 const char *filename,
296 unsigned line,
297 const char *section,
298 unsigned section_line,
299 const char *lvalue,
300 int ltype,
301 const char *rvalue,
302 void *data,
303 void *userdata) {
304
305 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
ca58d00c 306 FairQueueing *fq;
e83562e5
YW
307 Network *network = data;
308 usec_t sec;
309 int r;
310
311 assert(filename);
312 assert(lvalue);
313 assert(rvalue);
314 assert(data);
315
316 r = qdisc_new_static(QDISC_KIND_FQ, network, filename, section_line, &qdisc);
317 if (r == -ENOMEM)
318 return log_oom();
d96edb2c
YW
319 if (r < 0) {
320 log_syntax(unit, LOG_WARNING, filename, line, r,
321 "More than one kind of queueing discipline, ignoring assignment: %m");
322 return 0;
323 }
e83562e5
YW
324
325 fq = FQ(qdisc);
326
327 if (isempty(rvalue)) {
328 fq->ce_threshold_usec = USEC_INFINITY;
329
330 qdisc = NULL;
331 return 0;
332 }
333
334 r = parse_sec(rvalue, &sec);
335 if (r < 0) {
d96edb2c 336 log_syntax(unit, LOG_WARNING, filename, line, r,
e83562e5
YW
337 "Failed to parse '%s=', ignoring assignment: %s",
338 lvalue, rvalue);
339 return 0;
340 }
341 if (sec > UINT32_MAX) {
d96edb2c 342 log_syntax(unit, LOG_WARNING, filename, line, 0,
e83562e5
YW
343 "Specified '%s=' is too large, ignoring assignment: %s",
344 lvalue, rvalue);
345 return 0;
346 }
347
348 fq->ce_threshold_usec = sec;
349 qdisc = NULL;
350
351 return 0;
352}
353
949fb07e 354int config_parse_fair_queueing_max_rate(
e83562e5
YW
355 const char *unit,
356 const char *filename,
357 unsigned line,
358 const char *section,
359 unsigned section_line,
360 const char *lvalue,
361 int ltype,
362 const char *rvalue,
363 void *data,
364 void *userdata) {
365
366 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
ca58d00c 367 FairQueueing *fq;
e83562e5
YW
368 Network *network = data;
369 uint64_t sz;
370 int r;
371
372 assert(filename);
373 assert(lvalue);
374 assert(rvalue);
375 assert(data);
376
377 r = qdisc_new_static(QDISC_KIND_FQ, network, filename, section_line, &qdisc);
378 if (r == -ENOMEM)
379 return log_oom();
d96edb2c
YW
380 if (r < 0) {
381 log_syntax(unit, LOG_WARNING, filename, line, r,
382 "More than one kind of queueing discipline, ignoring assignment: %m");
383 return 0;
384 }
e83562e5
YW
385
386 fq = FQ(qdisc);
387
388 if (isempty(rvalue)) {
389 fq->max_rate = 0;
390
391 qdisc = NULL;
392 return 0;
393 }
394
395 r = parse_size(rvalue, 1000, &sz);
396 if (r < 0) {
d96edb2c 397 log_syntax(unit, LOG_WARNING, filename, line, r,
e83562e5
YW
398 "Failed to parse '%s=', ignoring assignment: %s",
399 lvalue, rvalue);
400 return 0;
401 }
402 if (sz / 8 > UINT32_MAX) {
d96edb2c 403 log_syntax(unit, LOG_WARNING, filename, line, 0,
e83562e5
YW
404 "Specified '%s=' is too large, ignoring assignment: %s",
405 lvalue, rvalue);
406 return 0;
407 }
408
409 fq->max_rate = sz / 8;
410 qdisc = NULL;
411
412 return 0;
413}
414
7234b915 415const QDiscVTable fq_vtable = {
949fb07e 416 .init = fair_queueing_init,
ca58d00c 417 .object_size = sizeof(FairQueueing),
7234b915 418 .tca_kind = "fq",
949fb07e 419 .fill_message = fair_queueing_fill_message,
7234b915 420};