]> git.pld-linux.org Git - packages/iproute2.git/blame - iproute2-2.2.4-wrr.patch
- updated to 2.6.18 s061002
[packages/iproute2.git] / iproute2-2.2.4-wrr.patch
CommitLineData
ca1c0e2c 1diff -uNrbB org/tc/Makefile new/tc/Makefile
2--- org/tc/Makefile Fri Feb 25 20:51:57 2000
3+++ new/tc/Makefile Mon Feb 12 17:24:48 2001
4@@ -9,6 +9,7 @@
5 TCMODULES += q_prio.o
6 TCMODULES += q_tbf.o
7 TCMODULES += q_cbq.o
8+TCMODULES += q_wrr.o
9 TCMODULES += f_rsvp.o
10 TCMODULES += f_u32.o
11 TCMODULES += f_route.o
12diff -uNrbB org/tc/q_wrr.c new/tc/q_wrr.c
13--- org/tc/q_wrr.c Thu Jan 1 01:00:00 1970
14+++ new/tc/q_wrr.c Sun Sep 9 12:44:28 2001
8db47f55 15@@ -0,0 +1,437 @@
ca1c0e2c 16+#include <stdio.h>
17+#include <stdlib.h>
18+#include <unistd.h>
19+#include <syslog.h>
20+#include <fcntl.h>
21+#include <sys/socket.h>
22+#include <netinet/in.h>
23+#include <arpa/inet.h>
24+#include <string.h>
25+#include <math.h>
26+
27+#include "utils.h"
28+#include "tc_util.h"
29+
30+#define usage() return(-1)
31+
8db47f55
JB
32+#ifdef NEED_WRR_DEFS
33+/* WRR section */
34+
35+/* Other includes */
36+#include <linux/if_ether.h>
37+
38+// A sub weight and of a class
39+// All numbers are represented as parts of (2^64-1).
40+struct tc_wrr_class_weight {
41+ __u64 val; // Current value (0 is not valid)
42+ __u64 decr; // Value pr bytes (2^64-1 is not valid)
43+ __u64 incr; // Value pr seconds (2^64-1 is not valid)
44+ __u64 min; // Minimal value (0 is not valid)
45+ __u64 max; // Minimal value (0 is not valid)
46+
47+ // The time where the above information was correct:
48+ time_t tim;
49+};
50+
51+// Pakcet send when modifying a class:
52+struct tc_wrr_class_modf {
53+ // Not-valid values are ignored.
54+ struct tc_wrr_class_weight weight1;
55+ struct tc_wrr_class_weight weight2;
56+};
57+
58+// Packet returned when quering a class:
59+struct tc_wrr_class_stats {
60+ char used; // If this is false the information below is invalid
61+
62+ struct tc_wrr_class_modf class_modf;
63+
64+ unsigned char addr[ETH_ALEN];
65+ char usemac; // True if addr is a MAC address, else it is an IP address
66+ // (this value is only for convience, it is always the same
67+ // value as in the qdisc)
68+ int heappos; // Current heap position or 0 if not in heap
69+ __u64 penal_ls; // Penalty value in heap (ls)
70+ __u64 penal_ms; // Penalty value in heap (ms)
71+};
72+
73+// Qdisc-wide penalty information (boolean values - 2 not valid)
74+struct tc_wrr_qdisc_weight {
75+ char weight_mode; // 0=No automatic change to weight
76+ // 1=Decrease normally
77+ // 2=Also multiply with number of machines
78+ // 3=Instead multiply with priority divided
79+ // with priority of the other.
80+ // -1=no change
81+};
82+
83+// Packet send when modifing a qdisc:
84+struct tc_wrr_qdisc_modf {
85+ // Not-valid values are ignored:
86+ struct tc_wrr_qdisc_weight weight1;
87+ struct tc_wrr_qdisc_weight weight2;
88+};
89+
90+// Packet send when creating a qdisc:
91+struct tc_wrr_qdisc_crt {
92+ struct tc_wrr_qdisc_modf qdisc_modf;
93+
94+ char srcaddr; // 1=lookup source, 0=lookup destination
95+ char usemac; // 1=Classify on MAC addresses, 0=classify on IP
96+ char usemasq; // 1=Classify based on masqgrading - only valid
97+ // if usemac is zero
98+ int bands_max; // Maximal number of bands (i.e.: classes)
99+ int proxy_maxconn; // If differnt from 0 then we support proxy remapping
100+ // of packets. And this is the number of maximal
101+ // concurrent proxy connections.
102+};
103+
104+// Packet returned when quering a qdisc:
105+struct tc_wrr_qdisc_stats {
106+ struct tc_wrr_qdisc_crt qdisc_crt;
107+ int proxy_curconn;
108+ int nodes_in_heap; // Current number of bands wanting to send something
109+ int bands_cur; // Current number of bands used (i.e.: MAC/IP addresses seen)
110+ int bands_reused; // Number of times this band has been reused.
111+ int packets_requed; // Number of times packets have been requeued.
112+ __u64 priosum; // Sum of priorities in heap where 1 is 2^32
113+};
114+
115+struct tc_wrr_qdisc_modf_std {
116+ // This indicates which of the tc_wrr_qdisc_modf structers this is:
117+ char proxy; // 0=This struct
118+
119+ // Should we also change a class?
120+ char change_class;
121+
122+ // Only valid if change_class is false
123+ struct tc_wrr_qdisc_modf qdisc_modf;
124+
125+ // Only valid if change_class is true:
126+ unsigned char addr[ETH_ALEN]; // Class to change (non-used bytes should be 0)
127+ struct tc_wrr_class_modf class_modf; // The change
128+};
129+
130+// Used for proxyrempping:
131+struct tc_wrr_qdisc_modf_proxy {
132+ // This indicates which of the tc_wrr_qdisc_modf structers this is:
133+ char proxy; // 1=This struct
134+
135+ // This is 1 if the proxyremap information should be reset
136+ char reset;
137+
138+ // changec is the number of elements in changes.
139+ int changec;
140+
141+ // This is an array of type ProxyRemapBlock:
142+ long changes[0];
143+};
144+#endif /* NEED_WRR_DEFS */
145+
ca1c0e2c 146+// Returns -1 on error
147+static int wrr_parse_qdisc_weight(int argc, char** argv,
148+ struct tc_wrr_qdisc_modf* opt) {
149+ int i;
150+
151+ opt->weight1.weight_mode=-1;
152+ opt->weight2.weight_mode=-1;
153+
154+ for(i=0; i<argc; i++) {
155+ if(!memcmp(argv[i],"wmode1=",7)) {
156+ opt->weight1.weight_mode=atoi(argv[i]+7);
157+ } else if(!memcmp(argv[i],"wmode2=",7)) {
158+ opt->weight2.weight_mode=atoi(argv[i]+7);
159+ } else {
160+ printf("Usage: ... [wmode1=0|1|2|3] [wmode2=0|1|2|3]\n");
161+ return -1;
162+ }
163+ }
164+ return 0;
165+}
166+
167+static int wrr_parse_class_modf(int argc, char** argv,
168+ struct tc_wrr_class_modf* modf) {
169+ int i;
170+
171+ if(argc<1) {
172+ fprintf(stderr, "Usage: ... [weight1=val] [decr1=val] [incr1=val] [min1=val] [max1=val] [val2=val] ...\n");
173+ fprintf(stderr, " The values can be floating point like 0.42 or divisions like 42/100\n");
174+ return -1;
175+ }
176+
177+ // Set meaningless values:
178+ modf->weight1.val=0;
179+ modf->weight1.decr=(__u64)-1;
180+ modf->weight1.incr=(__u64)-1;
181+ modf->weight1.min=0;
182+ modf->weight1.max=0;
183+ modf->weight2.val=0;
184+ modf->weight2.decr=(__u64)-1;
185+ modf->weight2.incr=(__u64)-1;
186+ modf->weight2.min=0;
187+ modf->weight2.max=0;
188+
189+ // And read values:
190+ for(i=0; i<argc; i++) {
191+ char arg[80];
192+ char* name,*value1=0,*value2=0;
193+ long double f_val1,f_val2=1,value;
194+ if(strlen(argv[i])>=sizeof(arg)) {
195+ fprintf(stderr,"Argument too long: %s\n",argv[i]);
196+ return -1;
197+ }
198+ strcpy(arg,argv[i]);
199+
200+ name=strtok(arg,"=");
201+ if(name) value1=strtok(0,"/");
202+ if(value1) value2=strtok(0,"");
203+
204+ if(!value1) {
205+ fprintf(stderr,"No = found in argument: %s\n",argv[i]);
206+ return -1;
207+ }
208+
209+ f_val1=atof(value1);
210+ if(value2) f_val2=atof(value2);
211+
212+ if(f_val2==0) {
213+ fprintf(stderr,"Division by 0\n");
214+ return -1;
215+ }
216+
217+ value=f_val1/f_val2;
218+ if(value>1) value=1;
219+ if(value<0) value=0;
220+ value*=((__u64)-1);
221+
222+ // And find the value set
223+ if(!strcmp(name,"weight1")) modf->weight1.val=value;
224+ else if(!strcmp(name,"decr1")) modf->weight1.decr=value;
225+ else if(!strcmp(name,"incr1")) modf->weight1.incr=value;
226+ else if(!strcmp(name,"min1")) modf->weight1.min=value;
227+ else if(!strcmp(name,"max1")) modf->weight1.max=value;
228+ else if(!strcmp(name,"weight2")) modf->weight2.val=value;
229+ else if(!strcmp(name,"decr2")) modf->weight2.decr=value;
230+ else if(!strcmp(name,"incr2")) modf->weight2.incr=value;
231+ else if(!strcmp(name,"min2")) modf->weight2.min=value;
232+ else if(!strcmp(name,"max2")) modf->weight2.max=value;
233+ else {
234+ fprintf(stderr,"illegal value: %s\n",name);
235+ return -1;
236+ }
237+ }
238+
239+ return 0;
240+}
241+
242+static int wrr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
243+{
244+ if(n->nlmsg_flags & NLM_F_CREATE) {
245+ // This is a create request:
246+ struct tc_wrr_qdisc_crt opt;
247+
248+ int sour,dest,ip,mac,masq;
249+
250+ if(argc<4) {
251+ fprintf(stderr, "Usage: ... wrr sour|dest ip|masq|mac maxclasses proxymaxcon [penalty-setup]\n");
252+ return -1;
253+ }
254+
255+ // Read sour/dest:
256+ memset(&opt,0,sizeof(opt));
257+ sour=!strcmp(argv[0],"sour");
258+ dest=!strcmp(argv[0],"dest");
259+
260+ if(!sour && !dest) {
261+ fprintf(stderr,"sour or dest must be specified\n");
262+ return -1;
263+ }
264+
265+ // Read ip/mac
266+ ip=!strcmp(argv[1],"ip");
267+ mac=!strcmp(argv[1],"mac");
268+ masq=!strcmp(argv[1],"masq");
269+
270+ if(!ip && !mac && !masq) {
271+ fprintf(stderr,"ip, masq or mac must be specified\n");
272+ return -1;
273+ }
274+
275+ opt.srcaddr=sour;
276+ opt.usemac=mac;
277+ opt.usemasq=masq;
278+ opt.bands_max=atoi(argv[2]);
279+
280+ opt.proxy_maxconn=atoi(argv[3]);
281+
282+ // Read weights:
283+ if(wrr_parse_qdisc_weight(argc-4,argv+4,&opt.qdisc_modf)<0) return -1;
284+ if(opt.qdisc_modf.weight1.weight_mode==-1) opt.qdisc_modf.weight1.weight_mode=0;
285+ if(opt.qdisc_modf.weight2.weight_mode==-1) opt.qdisc_modf.weight2.weight_mode=0;
286+
287+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
288+ } else {
289+ struct tc_wrr_qdisc_modf_std opt;
290+ char qdisc,class;
291+
292+ // This is a modify request:
293+ if(argc<1) {
294+ fprintf(stderr,"... qdisc ... or ... class ...\n");
295+ return -1;
296+ }
297+
298+ qdisc=!strcmp(argv[0],"qdisc");
299+ class=!strcmp(argv[0],"class");
300+
301+ if(!qdisc && !class) {
302+ fprintf(stderr,"qdisc or class must be specified\n");
303+ return -1;
304+ }
305+
306+ argc--;
307+ argv++;
308+
309+ opt.proxy=0;
310+
311+ if(qdisc) {
312+ opt.change_class=0;
313+ if(wrr_parse_qdisc_weight(argc, argv, &opt.qdisc_modf)<0) return -1;
314+ } else {
315+ int a0,a1,a2,a3,a4=0,a5=0;
316+
317+ opt.change_class=1;
318+
319+ if(argc<1) {
320+ fprintf(stderr,"... <mac>|<ip>|<masq> ...\n");
321+ return -1;
322+ }
323+ memset(opt.addr,0,sizeof(opt.addr));
324+
325+ if((sscanf(argv[0],"%i.%i.%i.%i",&a0,&a1,&a2,&a3)!=4) &&
326+ (sscanf(argv[0],"%x:%x:%x:%x:%x:%x",&a0,&a1,&a2,&a3,&a4,&a5)!=6)) {
327+ fprintf(stderr,"Wrong format of mac or ip address\n");
328+ return -1;
329+ }
330+
331+ opt.addr[0]=a0; opt.addr[1]=a1; opt.addr[2]=a2;
332+ opt.addr[3]=a3; opt.addr[4]=a4; opt.addr[5]=a5;
333+
334+ if(wrr_parse_class_modf(argc-1, argv+1, &opt.class_modf)<0) return -1;
335+ }
336+
337+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
338+ }
339+ return 0;
340+}
341+
342+static int wrr_parse_copt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) {
343+ struct tc_wrr_class_modf opt;
344+
345+ memset(&opt,0,sizeof(opt));
346+ if(wrr_parse_class_modf(argc,argv,&opt)<0) return -1;
347+
348+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
349+ return 0;
350+}
351+
352+static int wrr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
353+{
354+ struct tc_wrr_qdisc_stats *qopt;
355+
356+ if (opt == NULL)
357+ return 0;
358+
359+ if (RTA_PAYLOAD(opt) < sizeof(*qopt))
360+ return -1;
361+ qopt = RTA_DATA(opt);
362+
363+ fprintf(f,"\n (%s/%s) (maxclasses %i) (usedclasses %i) (reused classes %i)\n",
364+ qopt->qdisc_crt.srcaddr ? "sour" : "dest",
365+ qopt->qdisc_crt.usemac ? "mac" : (qopt->qdisc_crt.usemasq ? "masq" : "ip"),
366+ qopt->qdisc_crt.bands_max,
367+ qopt->bands_cur,
368+ qopt->bands_reused
369+ );
370+
371+ if(qopt->qdisc_crt.proxy_maxconn) {
372+ fprintf(f," (proxy maxcon %i) (proxy curcon %i)\n",
373+ qopt->qdisc_crt.proxy_maxconn,qopt->proxy_curconn);
374+ }
375+
376+ fprintf(f," (waiting classes %i) (packets requeued %i) (priosum: %Lg)\n",
377+ qopt->nodes_in_heap,
378+ qopt->packets_requed,
379+ qopt->priosum/((long double)((__u32)-1))
380+ );
381+
382+ fprintf(f," (wmode1 %i) (wmode2 %i) \n",
383+ qopt->qdisc_crt.qdisc_modf.weight1.weight_mode,
384+ qopt->qdisc_crt.qdisc_modf.weight2.weight_mode);
385+
386+ return 0;
387+}
388+
389+static int wrr_print_copt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) {
390+ struct tc_wrr_class_stats *copt;
391+ long double d=(__u64)-1;
392+
393+ if (opt == NULL) return 0;
394+
395+ if (RTA_PAYLOAD(opt) < sizeof(*copt))
396+ return -1;
397+ copt = RTA_DATA(opt);
398+
399+ if(!copt->used) {
400+ fprintf(f,"(unused)");
401+ return 0;
402+ }
403+
404+ if(copt->usemac) {
405+ fprintf(f,"\n (address: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X)\n",
406+ copt->addr[0],copt->addr[1],copt->addr[2],
407+ copt->addr[3],copt->addr[4],copt->addr[5]);
408+ } else {
409+ fprintf(f,"\n (address: %i.%i.%i.%i)\n",copt->addr[0],copt->addr[1],copt->addr[2],copt->addr[3]);
410+ }
411+
412+ fprintf(f," (total weight: %Lg) (current position: %i) (counters: %u %u : %u %u)\n",
413+ (copt->class_modf.weight1.val/d)*(copt->class_modf.weight2.val/d),
414+ copt->heappos,
415+ (unsigned)(copt->penal_ms>>32),
416+ (unsigned)(copt->penal_ms & 0xffffffffU),
417+ (unsigned)(copt->penal_ls>>32),
418+ (unsigned)(copt->penal_ls & 0xffffffffU)
419+ );
420+
421+ fprintf(f," Pars 1: (weight %Lg) (decr: %Lg) (incr: %Lg) (min: %Lg) (max: %Lg)\n",
422+ copt->class_modf.weight1.val/d,
423+ copt->class_modf.weight1.decr/d,
424+ copt->class_modf.weight1.incr/d,
425+ copt->class_modf.weight1.min/d,
426+ copt->class_modf.weight1.max/d);
427+
428+ fprintf(f," Pars 2: (weight %Lg) (decr: %Lg) (incr: %Lg) (min: %Lg) (max: %Lg)",
429+ copt->class_modf.weight2.val/d,
430+ copt->class_modf.weight2.decr/d,
431+ copt->class_modf.weight2.incr/d,
432+ copt->class_modf.weight2.min/d,
433+ copt->class_modf.weight2.max/d);
434+
435+ return 0;
436+}
437+
438+static int wrr_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
439+{
440+ return 0;
441+}
442+
443+
080dc5df 444+struct qdisc_util wrr_qdisc_util = {
ca1c0e2c 445+ NULL,
446+ "wrr",
447+ wrr_parse_opt,
448+ wrr_print_opt,
449+ wrr_print_xstats,
450+ wrr_parse_copt,
451+ wrr_print_copt
452+};
This page took 0.196844 seconds and 4 git commands to generate.