1 /* SPDX-License-Identifier: LGPL-2.1-or-later
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 "sfq.h"
12 #include "string-util.h"
13 
stochastic_fairness_queueing_fill_message(Link * link,QDisc * qdisc,sd_netlink_message * req)14 static int stochastic_fairness_queueing_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
15         StochasticFairnessQueueing *sfq;
16         int r;
17 
18         assert(link);
19         assert(qdisc);
20         assert(req);
21 
22         assert_se(sfq = SFQ(qdisc));
23 
24         const struct tc_sfq_qopt_v1 opt = {
25                 .v0.perturb_period = sfq->perturb_period / USEC_PER_SEC,
26         };
27 
28         r = sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(opt));
29         if (r < 0)
30                 return r;
31 
32         return 0;
33 }
34 
config_parse_stochastic_fairness_queueing_perturb_period(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)35 int config_parse_stochastic_fairness_queueing_perturb_period(
36                 const char *unit,
37                 const char *filename,
38                 unsigned line,
39                 const char *section,
40                 unsigned section_line,
41                 const char *lvalue,
42                 int ltype,
43                 const char *rvalue,
44                 void *data,
45                 void *userdata) {
46 
47         _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
48         StochasticFairnessQueueing *sfq;
49         Network *network = data;
50         int r;
51 
52         assert(filename);
53         assert(lvalue);
54         assert(rvalue);
55         assert(data);
56 
57         r = qdisc_new_static(QDISC_KIND_SFQ, network, filename, section_line, &qdisc);
58         if (r == -ENOMEM)
59                 return log_oom();
60         if (r < 0) {
61                 log_syntax(unit, LOG_WARNING, filename, line, r,
62                            "More than one kind of queueing discipline, ignoring assignment: %m");
63                 return 0;
64         }
65 
66         sfq = SFQ(qdisc);
67 
68         if (isempty(rvalue)) {
69                 sfq->perturb_period = 0;
70 
71                 TAKE_PTR(qdisc);
72                 return 0;
73         }
74 
75         r = parse_sec(rvalue, &sfq->perturb_period);
76         if (r < 0) {
77                 log_syntax(unit, LOG_WARNING, filename, line, r,
78                            "Failed to parse '%s=', ignoring assignment: %s",
79                            lvalue, rvalue);
80                 return 0;
81         }
82 
83         TAKE_PTR(qdisc);
84 
85         return 0;
86 }
87 
88 const QDiscVTable sfq_vtable = {
89         .object_size = sizeof(StochasticFairnessQueueing),
90         .tca_kind = "sfq",
91         .fill_message = stochastic_fairness_queueing_fill_message,
92 };
93