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