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 "netlink-util.h"
9 #include "parse-util.h"
10 #include "qdisc.h"
11 #include "sfb.h"
12 #include "string-util.h"
13
stochastic_fair_blue_fill_message(Link * link,QDisc * qdisc,sd_netlink_message * req)14 static int stochastic_fair_blue_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
15 StochasticFairBlue *sfb;
16 int r;
17
18 assert(link);
19 assert(qdisc);
20 assert(req);
21
22 assert_se(sfb = SFB(qdisc));
23
24 const struct tc_sfb_qopt opt = {
25 .rehash_interval = 600*1000,
26 .warmup_time = 60*1000,
27 .penalty_rate = 10,
28 .penalty_burst = 20,
29 .increment = (SFB_MAX_PROB + 1000) / 2000,
30 .decrement = (SFB_MAX_PROB + 10000) / 20000,
31 .max = 25,
32 .bin_size = 20,
33 .limit = sfb->packet_limit,
34 };
35
36 r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "sfb");
37 if (r < 0)
38 return r;
39
40 r = sd_netlink_message_append_data(req, TCA_SFB_PARMS, &opt, sizeof(opt));
41 if (r < 0)
42 return r;
43
44 r = sd_netlink_message_close_container(req);
45 if (r < 0)
46 return r;
47
48 return 0;
49 }
50
config_parse_stochastic_fair_blue_u32(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)51 int config_parse_stochastic_fair_blue_u32(
52 const char *unit,
53 const char *filename,
54 unsigned line,
55 const char *section,
56 unsigned section_line,
57 const char *lvalue,
58 int ltype,
59 const char *rvalue,
60 void *data,
61 void *userdata) {
62
63 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
64 StochasticFairBlue *sfb;
65 Network *network = data;
66 int r;
67
68 assert(filename);
69 assert(lvalue);
70 assert(rvalue);
71 assert(data);
72
73 r = qdisc_new_static(QDISC_KIND_SFB, network, filename, section_line, &qdisc);
74 if (r == -ENOMEM)
75 return log_oom();
76 if (r < 0) {
77 log_syntax(unit, LOG_WARNING, filename, line, r,
78 "More than one kind of queueing discipline, ignoring assignment: %m");
79 return 0;
80 }
81
82 sfb = SFB(qdisc);
83
84 if (isempty(rvalue)) {
85 sfb->packet_limit = 0;
86
87 TAKE_PTR(qdisc);
88 return 0;
89 }
90
91 r = safe_atou32(rvalue, &sfb->packet_limit);
92 if (r < 0) {
93 log_syntax(unit, LOG_WARNING, filename, line, r,
94 "Failed to parse '%s=', ignoring assignment: %s",
95 lvalue, rvalue);
96 return 0;
97 }
98
99 TAKE_PTR(qdisc);
100
101 return 0;
102 }
103
104 const QDiscVTable sfb_vtable = {
105 .object_size = sizeof(StochasticFairBlue),
106 .tca_kind = "sfb",
107 .fill_message = stochastic_fair_blue_fill_message,
108 };
109