1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * q_gred.c		GRED.
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * Authors:    J Hadi Salim(hadi@nortelnetworks.com)
10ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *             code ruthlessly ripped from
11ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *	       Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
241b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet#include <math.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h"
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_red.h"
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#if 0
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define DPRINTF(format,args...) fprintf(stderr,format,##args)
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#else
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define DPRINTF(format,args...)
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void explain(void)
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ... gred DP drop-probability limit BYTES "
41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    "min BYTES max BYTES\n");
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "    avpkt BYTES burst PACKETS probability PROBABILITY "
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    "bandwidth KBPS\n");
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "    [prio value]\n");
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr," OR ...\n");
46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr," gred setup DPs <num of DPs> default <default DP> "
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    "[grio]\n");
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
50ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemmingerstatic int init_gred(struct qdisc_util *qu, int argc, char **argv,
51ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger		     struct nlmsghdr *n)
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct rtattr *tail;
55cb4bd0ec8dcba856d1ebf8b3f72b79f669dad0f4Stephen Hemminger	struct tc_gred_sopt opt = { 0 };
56ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	int dps = 0;
57ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	int def_dp = -1;
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		DPRINTF(stderr,"init_gred: invoked with %s\n",*argv);
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(*argv, "DPs") == 0) {
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			DPRINTF(stderr,"init_gred: next_arg with %s\n",*argv);
64ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger			dps = strtol(*argv, (char **)NULL, 10);
65ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger			if (dps < 0 || dps >MAX_DPs) {
66ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger				fprintf(stderr, "DPs =%d\n", dps);
67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"DPs\"\n");
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "GRED: only %d DPs are "
69ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger					"currently supported\n",MAX_DPs);
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "default") == 0) {
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
74ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger			def_dp = strtol(*argv, (char **)NULL, 10);
751558971d43bbcd5db7f9be966654482a96179bf1Stephen Hemminger			if (dps == 0) {
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "\"default DP\" must be "
77ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger					"defined after DPs\n");
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
80ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger			if (def_dp < 0 || def_dp > dps) {
81ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger				fprintf(stderr,
82ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger					"\"default DP\" must be less than %d\n",
83ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger					opt.DPs);
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "grio") == 0) {
87cb4bd0ec8dcba856d1ebf8b3f72b79f669dad0f4Stephen Hemminger			opt.grio = 1;
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "help") == 0) {
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			explain();
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "What is \"%s\"?\n", *argv);
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			explain();
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--; argv++;
97ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	}
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
99ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	if (!dps || def_dp == -1) {
100ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger		fprintf(stderr, "Illegal gred setup parameters \n");
101ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger		return -1;
102ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	}
103ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger
104ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	opt.DPs = dps;
105ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	opt.def_DP = def_dp;
106ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger
107ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	DPRINTF("TC_GRED: sending DPs=%d default=%d\n",opt.DPs,opt.def_DP);
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->nlmsg_flags|=NLM_F_CREATE;
109228569c3ff79468f4c7580fd88b0d6a34ebdc311n);	tail = NLMSG_TAIL(n);
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addattr_l(n, 1024, TCA_GRED_DPS, &opt, sizeof(struct tc_gred_sopt));
112228569c3ff79468f4c7580fd88b0d6a34ebdc311void *) NLMSG_TAIL(n) - (void *) tail;	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
113ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger	return 0;
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger*/
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int ok=0;
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct tc_gred_qopt opt;
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned burst = 0;
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned avpkt = 0;
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	double probability = 0.02;
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned rate = 0;
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int wlog;
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	__u8 sbuf[256];
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct rtattr *tail;
1291b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	__u32 max_P;
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&opt, 0, sizeof(opt));
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(*argv, "limit") == 0) {
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_size(&opt.limit, *argv)) {
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"limit\"\n");
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "setup") == 0) {
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (ok) {
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"setup\"\n");
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return init_gred(qu,argc-1, argv+1,n);
147ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "min") == 0) {
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_size(&opt.qth_min, *argv)) {
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"min\"\n");
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "max") == 0) {
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_size(&opt.qth_max, *argv)) {
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"max\"\n");
159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "DP") == 0) {
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			opt.DP=strtol(*argv, (char **)NULL, 10);
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			DPRINTF ("\n ******* DP =%u\n",opt.DP);
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (opt.DP >MAX_DPs) { /* need a better error check */
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "DP =%u \n",opt.DP);
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"DP\"\n");
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "GRED: only %d DPs are currently supported\n",MAX_DPs);
170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "burst") == 0) {
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger                        if (get_unsigned(&burst, *argv, 0)) {
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"burst\"\n");
177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "avpkt") == 0) {
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_size(&avpkt, *argv)) {
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"avpkt\"\n");
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "probability") == 0) {
188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (sscanf(*argv, "%lg", &probability) != 1) {
190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"probability\"\n");
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "prio") == 0) {
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			opt.prio=strtol(*argv, (char **)NULL, 10);
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			/* some error check here */
198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "bandwidth") == 0) {
200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_rate(&rate, *argv)) {
202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "Illegal \"bandwidth\"\n");
203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ok++;
206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "help") == 0) {
207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			explain();
208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "What is \"%s\"?\n", *argv);
211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			explain();
212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--; argv++;
215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (rate == 0)
218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		get_rate(&rate, "10Mbit");
219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
220ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet	if (!opt.qth_min || !opt.qth_max || !opt.limit || !avpkt ||
221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    (opt.DP<0)) {
222ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet		fprintf(stderr, "Required parameter (min, max, limit, "
223ddf216c8631195549dbf84e4ebe3da1d77b45ce0Florian Westphal		    "avpkt, DP) is missing\n");
224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
226ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet	if (!burst) {
227ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet		burst = (2 * opt.qth_min + opt.qth_max) / (3 * avpkt);
228ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet		fprintf(stderr, "GRED: set burst to %u\n", burst);
229ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet	}
230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((wlog = tc_red_eval_ewma(opt.qth_min, burst, avpkt)) < 0) {
232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "GRED: failed to calculate EWMA constant.\n");
233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (wlog >= 10)
236ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet		fprintf(stderr, "GRED: WARNING. Burst %d seems to be too "
237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    "large.\n", burst);
238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	opt.Wlog = wlog;
239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((wlog = tc_red_eval_P(opt.qth_min, opt.qth_max, probability)) < 0) {
240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "GRED: failed to calculate probability.\n");
241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	opt.Plog = wlog;
244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((wlog = tc_red_eval_idle_damping(opt.Wlog, avpkt, rate, sbuf)) < 0)
245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    {
246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "GRED: failed to calculate idle damping "
247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    "table.\n");
248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	opt.Scell_log = wlog;
251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
252228569c3ff79468f4c7580fd88b0d6a34ebdc311n);	tail = NLMSG_TAIL(n);
253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addattr_l(n, 1024, TCA_GRED_PARMS, &opt, sizeof(opt));
255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addattr_l(n, 1024, TCA_GRED_STAB, sbuf, 256);
2561b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	max_P = probability * pow(2, 32);
2571b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	addattr32(n, 1024, TCA_GRED_MAX_P, max_P);
258228569c3ff79468f4c7580fd88b0d6a34ebdc311void *) NLMSG_TAIL(n) - (void *) tail;	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
2641b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	struct rtattr *tb[TCA_GRED_MAX + 1];
265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct tc_gred_qopt *qopt;
2661b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	__u32 *max_p = NULL;
267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int i;
268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	SPRINT_BUF(b1);
269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	SPRINT_BUF(b2);
270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	SPRINT_BUF(b3);
271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	SPRINT_BUF(b4);
272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	SPRINT_BUF(b5);
273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (opt == NULL)
275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
2771b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	parse_rtattr_nested(tb, TCA_GRED_MAX, opt);
278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (tb[TCA_GRED_PARMS] == NULL)
280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
281a5a6f1e80db7b124de236eb0dabafc7996c5f2f0osdl.net!shemminger
2821b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	if (tb[TCA_GRED_MAX_P] &&
2831b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet	    RTA_PAYLOAD(tb[TCA_GRED_MAX_P]) >= sizeof(__u32) * MAX_DPs)
2841b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet		max_p = RTA_DATA(tb[TCA_GRED_MAX_P]);
2851b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet
286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	qopt = RTA_DATA(tb[TCA_GRED_PARMS]);
287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (RTA_PAYLOAD(tb[TCA_GRED_PARMS])  < sizeof(*qopt)*MAX_DPs) {
288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f,"\n GRED received message smaller than expected\n");
289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
291ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* Bad hack! should really return a proper message as shown above*/
293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (i=0;i<MAX_DPs;i++, qopt++) {
295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (qopt->DP >= MAX_DPs) continue;
296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f, "\n DP:%d (prio %d) Average Queue %s Measured "
297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    "Queue %s  ",
298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->DP,
299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->prio,
300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			sprint_size(qopt->qave, b4),
301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			sprint_size(qopt->backlog, b5));
302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f, "\n\t Packet drops: %d (forced %d early %d)  ",
303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->forced+qopt->early,
304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->forced,
305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->early);
306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f, "\n\t Packet totals: %u (bytes %u)  ",
307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->packets,
308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			qopt->bytesin);
309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (show_details)
310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(f, "\n limit %s min %s max %s ",
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				sprint_size(qopt->limit, b1),
312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				sprint_size(qopt->qth_min, b2),
313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				sprint_size(qopt->qth_max, b3));
3141b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet		fprintf(f, "ewma %u ", qopt->Wlog);
3151b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet		if (max_p)
3161b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet			fprintf(f, "probability %lg ", max_p[i] / pow(2, 32));
3171b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet		else
3181b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet			fprintf(f, "Plog %u ", qopt->Plog);
3191b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet		fprintf(f, "Scell_log %u", qopt->Scell_log);
320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
32495812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaberstruct qdisc_util gred_qdisc_util = {
325f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger	.id		= "gred",
326f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger	.parse_qopt	= gred_parse_opt,
327f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger	.print_qopt	= gred_print_opt,
328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger};
329