1d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek/*
2d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek * q_sfb.c	Stochastic Fair Blue.
3d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *
4d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *		This program is free software; you can redistribute it and/or
5d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *		modify it under the terms of the GNU General Public License
6d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *		as published by the Free Software Foundation; either version
7d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *		2 of the License, or (at your option) any later version.
8d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *
9d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek * Authors:	Juliusz Chroboczek <jch@pps.jussieu.fr>
10d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek *
11d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek */
12d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
13d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
14d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
15d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <stdio.h>
16d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <stdlib.h>
17d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <unistd.h>
18d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <syslog.h>
19d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <fcntl.h>
20d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <sys/socket.h>
21d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <netinet/in.h>
22d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <arpa/inet.h>
23d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include <string.h>
24d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
25d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include "utils.h"
26d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek#include "tc_util.h"
27d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
28d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstatic void explain(void)
29d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek{
30d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	fprintf(stderr,
31d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"Usage: ... sfb [ rehash SECS ] [ db SECS ]\n"
32d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"	    [ limit PACKETS ] [ max PACKETS ] [ target PACKETS ]\n"
33d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"	    [ increment FLOAT ] [ decrement FLOAT ]\n"
34d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"	    [ penalty_rate PPS ] [ penalty_burst PACKETS ]\n");
35d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek}
36d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
37d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstatic int get_prob(__u32 *val, const char *arg)
38d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek{
39d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	double d;
40d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	char *ptr;
41d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
42d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (!arg || !*arg)
43d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		return -1;
44d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	d = strtod(arg, &ptr);
45d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (!ptr || ptr == arg || d < 0.0 || d > 1.0)
46d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		return -1;
47d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	*val = (__u32)(d * SFB_MAX_PROB + 0.5);
48d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	return 0;
49d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek}
50d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
51d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstatic int sfb_parse_opt(struct qdisc_util *qu, int argc, char **argv,
52d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			 struct nlmsghdr *n)
53d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek{
54d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	struct tc_sfb_qopt opt;
55d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	struct rtattr *tail;
56d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
57d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	memset(&opt, 0, sizeof(opt));
58d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.rehash_interval = 600*1000;
59d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.warmup_time = 60*1000;
60d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.penalty_rate = 10;
61d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.penalty_burst = 20;
62d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.increment = (SFB_MAX_PROB + 1000) / 2000;
63d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	opt.decrement = (SFB_MAX_PROB + 10000) / 20000;
64d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
65d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	while (argc > 0) {
66d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    if (strcmp(*argv, "rehash") == 0) {
67d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
68d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.rehash_interval, *argv, 0)) {
69d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"rehash\"\n");
70d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
71d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
72d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "db") == 0) {
73d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
74d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.warmup_time, *argv, 0)) {
75d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"db\"\n");
76d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
77d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
78d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "limit") == 0) {
79d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
80d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.limit, *argv, 0)) {
81d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"limit\"\n");
82d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
83d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
84d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "max") == 0) {
85d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
86d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.max, *argv, 0)) {
87d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"max\"\n");
88d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
89d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
90d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "target") == 0) {
91d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
92d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.bin_size, *argv, 0)) {
93d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"target\"\n");
94d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
95d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
96d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "increment") == 0) {
97d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
98d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_prob(&opt.increment, *argv)) {
99d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"increment\"\n");
100d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
101d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
102d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "decrement") == 0) {
103d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
104d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_prob(&opt.decrement, *argv)) {
105d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"decrement\"\n");
106d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
107d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
108d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "penalty_rate") == 0) {
109d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
110d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.penalty_rate, *argv, 0)) {
111d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"penalty_rate\"\n");
112d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
113d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
114d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else if (strcmp(*argv, "penalty_burst") == 0) {
115d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			NEXT_ARG();
116d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			if (get_u32(&opt.penalty_burst, *argv, 0)) {
117d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				fprintf(stderr, "Illegal \"penalty_burst\"\n");
118d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek				return -1;
119d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			}
120d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		} else {
121d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			fprintf(stderr, "What is \"%s\"?\n", *argv);
122d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			explain();
123d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			return -1;
124d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		}
125d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		argc--; argv++;
126d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	}
127d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
128d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (opt.max == 0) {
129d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		if (opt.bin_size >= 1)
130d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			opt.max = (opt.bin_size * 5 + 1) / 4;
131d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		else
132d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			opt.max = 25;
133d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	}
134d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (opt.bin_size == 0)
135d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		opt.bin_size = (opt.max * 4 + 3) / 5;
136d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
137d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	tail = NLMSG_TAIL(n);
138d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
139d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	addattr_l(n, 1024, TCA_SFB_PARMS, &opt, sizeof(opt));
140d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
141d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	return 0;
142d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek}
143d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
144d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstatic int sfb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
145d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek{
146d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	struct rtattr *tb[__TCA_SFB_MAX];
147d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	struct tc_sfb_qopt *qopt;
148d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
149d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (opt == NULL)
150d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		return 0;
151d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
152d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	parse_rtattr_nested(tb, TCA_SFB_MAX, opt);
153d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (tb[TCA_SFB_PARMS] == NULL)
154d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		return -1;
155d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	qopt = RTA_DATA(tb[TCA_SFB_PARMS]);
156d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	if (RTA_PAYLOAD(tb[TCA_SFB_PARMS]) < sizeof(*qopt))
157d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		return -1;
158d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
159d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	fprintf(f,
160d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"limit %d max %d target %d\n"
161d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"  increment %.5f decrement %.5f penalty rate %d burst %d "
162d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		"(%ums %ums)",
163d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		qopt->limit, qopt->max, qopt->bin_size,
164d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		(double)qopt->increment / SFB_MAX_PROB,
165d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		(double)qopt->decrement / SFB_MAX_PROB,
166d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		qopt->penalty_rate, qopt->penalty_burst,
167d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		qopt->rehash_interval, qopt->warmup_time);
168d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
169d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	return 0;
170d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek}
171d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
172d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstatic int sfb_print_xstats(struct qdisc_util *qu, FILE *f,
173d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek			    struct rtattr *xstats)
174d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek{
175d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    struct tc_sfb_xstats *st;
176d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
177d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    if (xstats == NULL)
178d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    return 0;
179d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
180d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    if (RTA_PAYLOAD(xstats) < sizeof(*st))
181d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    return -1;
182d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
183d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    st = RTA_DATA(xstats);
184d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    fprintf(f,
185d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    "  earlydrop %u penaltydrop %u bucketdrop %u queuedrop %u childdrop %u marked %u\n"
186d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    "  maxqlen %u maxprob %.5f avgprob %.5f ",
187d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    st->earlydrop, st->penaltydrop, st->bucketdrop, st->queuedrop, st->childdrop,
188d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    st->marked,
189d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	    st->maxqlen, (double)st->maxprob / SFB_MAX_PROB,
190d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek		(double)st->avgprob / SFB_MAX_PROB);
191d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
192d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek    return 0;
193d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek}
194d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek
195d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczekstruct qdisc_util sfb_qdisc_util = {
196d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	.id		= "sfb",
197d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	.parse_qopt	= sfb_parse_opt,
198d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	.print_qopt	= sfb_print_opt,
199d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek	.print_xstats	= sfb_print_xstats,
200d7f3299d591e31f84ea3b8d4549d4019da1f9a7bJuliusz Chroboczek};
201