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
= NLMSG_TAIL(n
);
136 addattr_l(n
, 1024, TCA_OPTIONS
, NULL
, 0);
137 addattr_l(n
, 1024, TCA_SFB_PARMS
, &opt
, sizeof(opt
));
138 tail
->rta_len
= (void *) NLMSG_TAIL(n
) - (void *) tail
;
142 static int sfb_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
144 struct rtattr
*tb
[__TCA_SFB_MAX
];
145 struct tc_sfb_qopt
*qopt
;
150 parse_rtattr_nested(tb
, TCA_SFB_MAX
, opt
);
151 if (tb
[TCA_SFB_PARMS
] == NULL
)
153 qopt
= RTA_DATA(tb
[TCA_SFB_PARMS
]);
154 if (RTA_PAYLOAD(tb
[TCA_SFB_PARMS
]) < sizeof(*qopt
))
158 "limit %d max %d target %d\n"
159 " increment %.5f decrement %.5f penalty rate %d burst %d (%ums %ums)",
160 qopt
->limit
, qopt
->max
, qopt
->bin_size
,
161 (double)qopt
->increment
/ SFB_MAX_PROB
,
162 (double)qopt
->decrement
/ SFB_MAX_PROB
,
163 qopt
->penalty_rate
, qopt
->penalty_burst
,
164 qopt
->rehash_interval
, qopt
->warmup_time
);
169 static int sfb_print_xstats(struct qdisc_util
*qu
, FILE *f
,
170 struct rtattr
*xstats
)
172 struct tc_sfb_xstats
*st
;
177 if (RTA_PAYLOAD(xstats
) < sizeof(*st
))
180 st
= RTA_DATA(xstats
);
182 " earlydrop %u penaltydrop %u bucketdrop %u queuedrop %u childdrop %u marked %u\n"
183 " maxqlen %u maxprob %.5f avgprob %.5f ",
184 st
->earlydrop
, st
->penaltydrop
, st
->bucketdrop
, st
->queuedrop
, st
->childdrop
,
186 st
->maxqlen
, (double)st
->maxprob
/ SFB_MAX_PROB
,
187 (double)st
->avgprob
/ SFB_MAX_PROB
);
192 struct qdisc_util sfb_qdisc_util
= {
194 .parse_qopt
= sfb_parse_opt
,
195 .print_qopt
= sfb_print_opt
,
196 .print_xstats
= sfb_print_xstats
,