2 * q_sfb.c Stochastic Fair Blue.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Juliusz Chroboczek <jch@pps.jussieu.fr>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
27 static void explain(void)
30 "Usage: ... sfb [ rehash SECS ] [ db SECS ]\n"
31 " [ limit PACKETS ] [ max PACKETS ] [ target PACKETS ]\n"
32 " [ increment FLOAT ] [ decrement FLOAT ]\n"
33 " [ penalty_rate PPS ] [ penalty_burst PACKETS ]\n");
36 static int get_prob(__u32
*val
, const char *arg
)
43 d
= strtod(arg
, &ptr
);
44 if (!ptr
|| ptr
== arg
|| d
< 0.0 || d
> 1.0)
46 *val
= (__u32
)(d
* SFB_MAX_PROB
+ 0.5);
50 static int sfb_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
51 struct nlmsghdr
*n
, const char *dev
)
53 struct tc_sfb_qopt opt
= {
54 .rehash_interval
= 600*1000,
55 .warmup_time
= 60*1000,
58 .increment
= (SFB_MAX_PROB
+ 1000) / 2000,
59 .decrement
= (SFB_MAX_PROB
+ 10000) / 20000,
64 if (strcmp(*argv
, "rehash") == 0) {
66 if (get_u32(&opt
.rehash_interval
, *argv
, 0)) {
67 fprintf(stderr
, "Illegal \"rehash\"\n");
70 } else if (strcmp(*argv
, "db") == 0) {
72 if (get_u32(&opt
.warmup_time
, *argv
, 0)) {
73 fprintf(stderr
, "Illegal \"db\"\n");
76 } else if (strcmp(*argv
, "limit") == 0) {
78 if (get_u32(&opt
.limit
, *argv
, 0)) {
79 fprintf(stderr
, "Illegal \"limit\"\n");
82 } else if (strcmp(*argv
, "max") == 0) {
84 if (get_u32(&opt
.max
, *argv
, 0)) {
85 fprintf(stderr
, "Illegal \"max\"\n");
88 } else if (strcmp(*argv
, "target") == 0) {
90 if (get_u32(&opt
.bin_size
, *argv
, 0)) {
91 fprintf(stderr
, "Illegal \"target\"\n");
94 } else if (strcmp(*argv
, "increment") == 0) {
96 if (get_prob(&opt
.increment
, *argv
)) {
97 fprintf(stderr
, "Illegal \"increment\"\n");
100 } else if (strcmp(*argv
, "decrement") == 0) {
102 if (get_prob(&opt
.decrement
, *argv
)) {
103 fprintf(stderr
, "Illegal \"decrement\"\n");
106 } else if (strcmp(*argv
, "penalty_rate") == 0) {
108 if (get_u32(&opt
.penalty_rate
, *argv
, 0)) {
109 fprintf(stderr
, "Illegal \"penalty_rate\"\n");
112 } else if (strcmp(*argv
, "penalty_burst") == 0) {
114 if (get_u32(&opt
.penalty_burst
, *argv
, 0)) {
115 fprintf(stderr
, "Illegal \"penalty_burst\"\n");
119 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
127 if (opt
.bin_size
>= 1)
128 opt
.max
= (opt
.bin_size
* 5 + 1) / 4;
132 if (opt
.bin_size
== 0)
133 opt
.bin_size
= (opt
.max
* 4 + 3) / 5;
135 tail
= addattr_nest(n
, 1024, TCA_OPTIONS
);
136 addattr_l(n
, 1024, TCA_SFB_PARMS
, &opt
, sizeof(opt
));
137 addattr_nest_end(n
, tail
);
141 static int sfb_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
143 struct rtattr
*tb
[__TCA_SFB_MAX
];
144 struct tc_sfb_qopt
*qopt
;
149 parse_rtattr_nested(tb
, TCA_SFB_MAX
, opt
);
150 if (tb
[TCA_SFB_PARMS
] == NULL
)
152 qopt
= RTA_DATA(tb
[TCA_SFB_PARMS
]);
153 if (RTA_PAYLOAD(tb
[TCA_SFB_PARMS
]) < sizeof(*qopt
))
157 "limit %d max %d target %d\n"
158 " increment %.5f decrement %.5f penalty rate %d burst %d (%ums %ums)",
159 qopt
->limit
, qopt
->max
, qopt
->bin_size
,
160 (double)qopt
->increment
/ SFB_MAX_PROB
,
161 (double)qopt
->decrement
/ SFB_MAX_PROB
,
162 qopt
->penalty_rate
, qopt
->penalty_burst
,
163 qopt
->rehash_interval
, qopt
->warmup_time
);
168 static int sfb_print_xstats(struct qdisc_util
*qu
, FILE *f
,
169 struct rtattr
*xstats
)
171 struct tc_sfb_xstats
*st
;
176 if (RTA_PAYLOAD(xstats
) < sizeof(*st
))
179 st
= RTA_DATA(xstats
);
181 " earlydrop %u penaltydrop %u bucketdrop %u queuedrop %u childdrop %u marked %u\n"
182 " maxqlen %u maxprob %.5f avgprob %.5f ",
183 st
->earlydrop
, st
->penaltydrop
, st
->bucketdrop
, st
->queuedrop
, st
->childdrop
,
185 st
->maxqlen
, (double)st
->maxprob
/ SFB_MAX_PROB
,
186 (double)st
->avgprob
/ SFB_MAX_PROB
);
191 struct qdisc_util sfb_qdisc_util
= {
193 .parse_qopt
= sfb_parse_opt
,
194 .print_qopt
= sfb_print_opt
,
195 .print_xstats
= sfb_print_xstats
,