1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2 * Copyright © 2020 VMware, Inc. */
3
4 #include <linux/pkt_sched.h>
5
6 #include "alloc-util.h"
7 #include "conf-parser.h"
8 #include "fq-pie.h"
9 #include "netlink-util.h"
10 #include "parse-util.h"
11 #include "string-util.h"
12
fq_pie_fill_message(Link * link,QDisc * qdisc,sd_netlink_message * req)13 static int fq_pie_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
14 FlowQueuePIE *fq_pie;
15 int r;
16
17 assert(link);
18 assert(qdisc);
19 assert(req);
20
21 assert_se(fq_pie = FQ_PIE(qdisc));
22
23 r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "fq_pie");
24 if (r < 0)
25 return r;
26
27 if (fq_pie->packet_limit > 0) {
28 r = sd_netlink_message_append_u32(req, TCA_FQ_PIE_LIMIT, fq_pie->packet_limit);
29 if (r < 0)
30 return r;
31 }
32
33 r = sd_netlink_message_close_container(req);
34 if (r < 0)
35 return r;
36
37 return 0;
38 }
39
config_parse_fq_pie_packet_limit(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)40 int config_parse_fq_pie_packet_limit(
41 const char *unit,
42 const char *filename,
43 unsigned line,
44 const char *section,
45 unsigned section_line,
46 const char *lvalue,
47 int ltype,
48 const char *rvalue,
49 void *data,
50 void *userdata) {
51
52 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
53 FlowQueuePIE *fq_pie;
54 Network *network = data;
55 uint32_t val;
56 int r;
57
58 assert(filename);
59 assert(lvalue);
60 assert(rvalue);
61 assert(data);
62
63 r = qdisc_new_static(QDISC_KIND_FQ_PIE, network, filename, section_line, &qdisc);
64 if (r == -ENOMEM)
65 return log_oom();
66 if (r < 0)
67 return log_syntax(unit, LOG_WARNING, filename, line, r,
68 "More than one kind of queueing discipline, ignoring assignment: %m");
69
70 fq_pie = FQ_PIE(qdisc);
71
72 if (isempty(rvalue)) {
73 fq_pie->packet_limit = 0;
74
75 qdisc = NULL;
76 return 0;
77 }
78
79 r = safe_atou32(rvalue, &val);
80 if (r < 0) {
81 log_syntax(unit, LOG_WARNING, filename, line, r,
82 "Failed to parse '%s=', ignoring assignment: %s",
83 lvalue, rvalue);
84 return 0;
85 }
86 if (val == 0) {
87 log_syntax(unit, LOG_WARNING, filename, line, 0,
88 "Invalid '%s=', ignoring assignment: %s",
89 lvalue, rvalue);
90 return 0;
91 }
92
93 fq_pie->packet_limit = val;
94 qdisc = NULL;
95
96 return 0;
97 }
98
99 const QDiscVTable fq_pie_vtable = {
100 .object_size = sizeof(FlowQueuePIE),
101 .tca_kind = "fq_pie",
102 .fill_message = fq_pie_fill_message,
103 };
104