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