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 "pie.h"
9 #include "netlink-util.h"
10 #include "parse-util.h"
11 #include "string-util.h"
12 
pie_fill_message(Link * link,QDisc * qdisc,sd_netlink_message * req)13 static int pie_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
14         ProportionalIntegralControllerEnhanced *pie;
15         int r;
16 
17         assert(link);
18         assert(qdisc);
19         assert(req);
20 
21         assert_se(pie = PIE(qdisc));
22 
23         r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "pie");
24         if (r < 0)
25                 return r;
26 
27         if (pie->packet_limit > 0) {
28                 r = sd_netlink_message_append_u32(req, TCA_PIE_LIMIT, 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_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_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         ProportionalIntegralControllerEnhanced *pie;
54         Network *network = data;
55         int r;
56 
57         assert(filename);
58         assert(lvalue);
59         assert(rvalue);
60         assert(data);
61 
62         r = qdisc_new_static(QDISC_KIND_PIE, network, filename, section_line, &qdisc);
63         if (r == -ENOMEM)
64                 return log_oom();
65         if (r < 0) {
66                 log_syntax(unit, LOG_WARNING, filename, line, r,
67                            "More than one kind of queueing discipline, ignoring assignment: %m");
68                 return 0;
69         }
70 
71         pie = PIE(qdisc);
72 
73         if (isempty(rvalue)) {
74                 pie->packet_limit = 0;
75 
76                 TAKE_PTR(qdisc);
77                 return 0;
78         }
79 
80         r = safe_atou32(rvalue, &pie->packet_limit);
81         if (r < 0) {
82                 log_syntax(unit, LOG_WARNING, filename, line, r,
83                            "Failed to parse '%s=', ignoring assignment: %s",
84                            lvalue, rvalue);
85                 return 0;
86         }
87 
88         TAKE_PTR(qdisc);
89 
90         return 0;
91 }
92 
93 const QDiscVTable pie_vtable = {
94         .object_size = sizeof(ProportionalIntegralControllerEnhanced),
95         .tca_kind = "pie",
96         .fill_message = pie_fill_message,
97 };
98