]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - config/qos/makeqosscripts.pl
c3dac4044afede0a14f051fe76d8b58ff89c6e4a
[people/pmueller/ipfire-2.x.git] / config / qos / makeqosscripts.pl
1 #!/usr/bin/perl
2 #
3 # IPFire Scripts
4 #
5 # This code is distributed under the terms of the GPL
6 #
7 # (c) The IPFire Team
8 #
9
10 use strict;
11 # enable only the following on debugging purpose
12 # use warnings;
13
14 require '/var/ipfire/general-functions.pl';
15 require "${General::swroot}/lang.pl";
16 require "${General::swroot}/header.pl";
17
18 my %qossettings = ();
19 my %checked = ();
20 my %netsettings = ();
21 my $message = "";
22 my $errormessage = "";
23 my $c = "";
24 my $direntry = "";
25 my $classentry = "";
26 my $subclassentry = "";
27 my $l7ruleentry = "";
28 my $portruleentry = "";
29 my $tosruleentry = "";
30 my @tmp = ();
31 my @classes = ();
32 my @subclasses = ();
33 my @l7rules = ();
34 my @portrules = ();
35 my @tosrules = ();
36 my @tmpline = ();
37 my @classline = ();
38 my @subclassline = ();
39 my @tosruleline = ();
40 my @l7ruleline = ();
41 my @portruleline = ();
42 my @proto = ();
43 my %selected= () ;
44 my $classfile = "/var/ipfire/qos/classes";
45 my $subclassfile = "/var/ipfire/qos/subclasses";
46 my $level7file = "/var/ipfire/qos/level7config";
47 my $portfile = "/var/ipfire/qos/portconfig";
48 my $tosfile = "/var/ipfire/qos/tosconfig";
49
50 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
51
52 $qossettings{'ENABLED'} = 'off';
53 $qossettings{'EDIT'} = 'no';
54 $qossettings{'OUT_SPD'} = '';
55 $qossettings{'INC_SPD'} = '';
56 $qossettings{'DEF_OUT_SPD'} = '';
57 $qossettings{'DEF_INC_SPD'} = '';
58 $qossettings{'DEFCLASS_INC'} = '';
59 $qossettings{'DEFCLASS_OUT'} = '';
60 $qossettings{'ACK'} = '';
61 $qossettings{'MTU'} = '1492';
62 $qossettings{'RED_DEV'} = `cat /var/ipfire/red/iface`;
63 $qossettings{'IMQ_DEV'} = 'imq0';
64 $qossettings{'TOS'} = '';
65 $qossettings{'VALID'} = 'yes';
66
67 &General::readhash("${General::swroot}/qos/settings", \%qossettings);
68
69 open( FILE, "< $classfile" ) or die "Unable to read $classfile";
70 @classes = <FILE>;
71 close FILE;
72 open( FILE, "< $subclassfile" ) or die "Unable to read $subclassfile";
73 @subclasses = <FILE>;
74 close FILE;
75 open( FILE, "< $level7file" ) or die "Unable to read $level7file";
76 @l7rules = <FILE>;
77 close FILE;
78 open( FILE, "< $portfile" ) or die "Unable to read $portfile";
79 @portrules = <FILE>;
80 close FILE;
81 open( FILE, "< $tosfile" ) or die "Unable to read $tosfile";
82 @tosrules = <FILE>;
83 close FILE;
84
85 ############################################################################################################################
86 ############################################################################################################################
87
88 print <<END
89 #/bin/bash
90 #################################################
91 # This is an autocreated QoS-Script for #
92 # IPFIRE #
93 # Copyright by the IPFire Team (GPLv2) #
94 # www.ipfire.org #
95 #################################################
96
97 ### SYSTEMVARIABLES:
98 # RED INTERFACE: $qossettings{'RED_DEV'}
99 # IMQ DEVICE: $qossettings{'IMQ_DEV'}
100
101 case "\$1" in
102
103 status)
104 case "\$2" in
105 qdisc)
106 echo "[qdisc]"
107 tc -s qdisc show dev $qossettings{'RED_DEV'}
108 tc -s qdisc show dev $qossettings{'IMQ_DEV'}
109 exit 0
110 ;;
111 class)
112 echo "[class]"
113 tc -s class show dev $qossettings{'RED_DEV'}
114 tc -s class show dev $qossettings{'IMQ_DEV'}
115 exit 0
116 ;;
117 filter)
118 echo "[filter]"
119 tc -s filter show dev $qossettings{'RED_DEV'}
120 tc -s filter show dev $qossettings{'IMQ_DEV'}
121 exit 0
122 ;;
123 iptables)
124 echo "[iptables]"
125 iptables -t mangle -n -L QOS-OUT -v -x 2> /dev/null
126 iptables -t mangle -n -L QOS-INC -v -x 2> /dev/null
127 iptables -t mangle -n -L QOS-TOS -v -x 2> /dev/null
128 exit 0
129 ;;
130 esac
131 \$0 \$1 qdisc
132 \$0 \$1 class
133 \$0 \$1 filter
134 \$0 \$1 iptables
135 exit 0
136 ;;
137 start)
138 ###
139 ### $qossettings{'RED_DEV'}
140 ###
141
142 ### INIT KERNEL
143 modprobe sch_htb
144
145 ### SET QUEUE LENGTH & MTU - has just to be tested!!! IMPORTANT
146 ip link set dev $qossettings{'RED_DEV'} qlen $qossettings{'QLENGTH'}
147 ip link set dev $qossettings{'RED_DEV'} mtu $qossettings{'MTU'}
148
149 ### ADD HTB QDISC FOR $qossettings{'RED_DEV'}
150 tc qdisc add dev $qossettings{'RED_DEV'} root handle 1: htb default $qossettings{'DEFCLASS_OUT'}
151
152 ### MAIN RATE LIMIT
153 tc class add dev $qossettings{'RED_DEV'} parent 1: classid 1:1 htb rate $qossettings{'OUT_SPD'}kbit
154
155 ### CLASSES FOR $qossettings{'RED_DEV'}
156 END
157 ;
158 foreach $classentry (sort @classes)
159 {
160 @classline = split( /\;/, $classentry );
161 if ($qossettings{'RED_DEV'} eq $classline[0]) {
162 $qossettings{'DEVICE'} = $classline[0];
163 $qossettings{'CLASS'} = $classline[1];
164 $qossettings{'PRIO'} = $classline[2];
165 $qossettings{'RATE'} = $classline[3];
166 $qossettings{'CEIL'} = $classline[4];
167 $qossettings{'BURST'} = $classline[5];
168 $qossettings{'CBURST'} = $classline[6];
169 print "\ttc class add dev $qossettings{'DEVICE'} parent 1:1 classid 1:$qossettings{'CLASS'} htb rate $qossettings{'RATE'}kbit ceil $qossettings{'CEIL'}kbit prio $qossettings{'PRIO'} ";
170 if (($qossettings{'BURST'} ne '') && ($qossettings{'BURST'} ne 0)) {
171 print "burst $qossettings{'BURST'}k ";
172 }
173 if (($qossettings{'CBURST'} ne '') && ($qossettings{'CBURST'} ne 0)) {
174 print "cburst $qossettings{'CBURST'}k";
175 }
176 print "\n";
177 }
178 }
179 foreach $subclassentry (sort @subclasses) {
180 @subclassline = split( /\;/, $subclassentry );
181 if ($qossettings{'RED_DEV'} eq $subclassline[0]) {
182 $qossettings{'DEVICE'} = $subclassline[0];
183 $qossettings{'CLASS'} = $subclassline[1];
184 $qossettings{'SCLASS'} = $subclassline[2];
185 $qossettings{'SPRIO'} = $subclassline[3];
186 $qossettings{'SRATE'} = $subclassline[4];
187 $qossettings{'SCEIL'} = $subclassline[5];
188 $qossettings{'SBURST'} = $subclassline[6];
189 $qossettings{'SCBURST'} = $subclassline[7];
190 print "\ttc class add dev $qossettings{'DEVICE'} parent 1:$qossettings{'CLASS'} classid 1:$qossettings{'SCLASS'} htb rate $qossettings{'SRATE'}kbit ceil $qossettings{'SCEIL'}kbit prio $qossettings{'SPRIO'} ";
191 if ($qossettings{'SBURST'} > 0) {
192 print "burst $qossettings{'SBURST'}k ";
193 }
194 if (($qossettings{'SCBURST'} ne '') && ($qossettings{'SCBURST'} ne 0)) {
195 print "cburst $qossettings{'CBURST'}k";
196 }
197 print "\n";
198 }
199 }
200
201 print "\n\t### ATTACH QDISC TO LEAF CLASSES\n";
202 foreach $classentry (sort @classes)
203 {
204 @classline = split( /\;/, $classentry );
205 if ($qossettings{'RED_DEV'} eq $classline[0]) {
206 $qossettings{'DEVICE'} = $classline[0];
207 $qossettings{'CLASS'} = $classline[1];
208 print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 1:$qossettings{'CLASS'} handle $qossettings{'CLASS'}: sfq perturb $qossettings{'SFQ_PERTUB'}\n";
209 }
210 }
211 foreach $subclassentry (sort @subclasses) {
212 @subclassline = split( /\;/, $subclassentry );
213 if ($qossettings{'RED_DEV'} eq $subclassline[0]) {
214 $qossettings{'DEVICE'} = $subclassline[0];
215 $qossettings{'SCLASS'} = $subclassline[2];
216 print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 1:$qossettings{'SCLASS'} handle $qossettings{'SCLASS'}: sfq perturb $qossettings{'SFQ_PERTUB'}\n";
217 }
218 }
219 print "\n\t### FILTER TRAFFIC INTO CLASSES\n";
220 foreach $classentry (sort @classes)
221 {
222 @classline = split( /\;/, $classentry );
223 if ($qossettings{'RED_DEV'} eq $classline[0]) {
224 $qossettings{'DEVICE'} = $classline[0];
225 $qossettings{'CLASS'} = $classline[1];
226 print "\ttc filter add dev $qossettings{'DEVICE'} parent 1:0 prio 0 protocol ip handle $qossettings{'CLASS'} fw flowid 1:$qossettings{'CLASS'}\n";
227 }
228 }
229 foreach $subclassentry (sort @subclasses) {
230 @subclassline = split( /\;/, $subclassentry );
231 if ($qossettings{'RED_DEV'} eq $subclassline[0]) {
232 $qossettings{'DEVICE'} = $subclassline[0];
233 $qossettings{'CLASS'} = $subclassline[1];
234 $qossettings{'SCLASS'} = $subclassline[2];
235 print "\ttc filter add dev $qossettings{'DEVICE'} parent 1:0 prio 0 protocol ip handle $qossettings{'SCLASS'} fw flowid 1:$qossettings{'SCLASS'}\n";
236 }
237 }
238 print <<END
239
240 ### ADD QOS-OUT CHAIN TO THE MANGLE TABLE IN IPTABLES
241 iptables -t mangle -N QOS-OUT
242 iptables -t mangle -N QOS-TOS
243 iptables -t mangle -I POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-OUT
244 iptables -t mangle -A POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-TOS
245
246 ### MARK ACKs
247 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags SYN,RST SYN -j TOS --set-tos 4
248 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags SYN,RST SYN -j MARK --set-mark $qossettings{'ACK'}
249 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags SYN,RST SYN -j RETURN
250
251 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p icmp -m length --length 40:100 -j MARK --set-mark $qossettings{'ACK'}
252 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p icmp -m length --length 40:100 -j RETURN
253
254 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --syn -m length --length 40:68 -j TOS --set-tos 4
255 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --syn -m length --length 40:68 -j MARK --set-mark $qossettings{'ACK'}
256 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --syn -m length --length 40:68 -j RETURN
257
258 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 -j TOS --set-tos 4
259 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 -j MARK --set-mark $qossettings{'ACK'}
260 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 -j RETURN
261
262 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK -m length --length 40:100 -j TOS --set-tos 4
263 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK -m length --length 40:100 -j MARK --set-mark $qossettings{'ACK'}
264 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK -m length --length 40:100 -j RETURN
265
266 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL RST -j TOS --set-tos 4
267 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL RST -j MARK --set-mark $qossettings{'ACK'}
268 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL RST -j RETURN
269
270 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,RST -j TOS --set-tos 4
271 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,RST -j MARK --set-mark $qossettings{'ACK'}
272 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,RST -j RETURN
273
274 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,FIN -j TOS --set-tos 4
275 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,FIN -j MARK --set-mark $qossettings{'ACK'}
276 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -p tcp --tcp-flags ALL ACK,FIN -j RETURN
277
278 ### SET TOS
279 END
280 ;
281 foreach $tosruleentry (sort @tosrules)
282 {
283 @tosruleline = split( /\;/, $tosruleentry );
284 $qossettings{'CLASS'} = $tosruleline[0];
285 $qossettings{'TOS'} = abs $tosruleline[2] * 2;
286 if ( $tosruleline[1] eq $qossettings{'RED_DEV'} )
287 {
288 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -m tos --tos $qossettings{'TOS'} -j MARK --set-mark $qossettings{'CLASS'}\n";
289 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -m tos --tos $qossettings{'TOS'} -j RETURN\n";
290 }
291 }
292
293 print "\n\t### SET PORT-RULES\n";
294 foreach $portruleentry (sort @portrules)
295 {
296 @portruleline = split( /\;/, $portruleentry );
297 if ( $portruleline[1] eq $qossettings{'RED_DEV'} )
298 {
299 $qossettings{'CLASS'} = $portruleline[0];
300 $qossettings{'DEVICE'} = $portruleline[1];
301 $qossettings{'PPROT'} = $portruleline[2];
302 $qossettings{'QIP'} = $portruleline[3];
303 $qossettings{'QPORT'} = $portruleline[4];
304 $qossettings{'DIP'} = $portruleline[5];
305 $qossettings{'DPORT'} = $portruleline[6];
306 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
307 if ($qossettings{'QIP'} ne ''){
308 print "-s $qossettings{'QIP'} ";
309 }
310 if ($qossettings{'DIP'} ne ''){
311 print "-d $qossettings{'DIP'} ";
312 }
313 print "-p $qossettings{'PPROT'} ";
314 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
315 print "-m multiport ";
316 }
317 if ($qossettings{'QPORT'} ne ''){
318 print "--sport $qossettings{'QPORT'} ";
319 }
320 if ($qossettings{'DPORT'} ne ''){
321 print "--dport $qossettings{'DPORT'} ";
322 }
323 print "-j MARK --set-mark $qossettings{'CLASS'}\n";
324 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
325 if ($qossettings{'QIP'} ne ''){
326 print "-s $qossettings{'QIP'} ";
327 }
328 if ($qossettings{'DIP'} ne ''){
329 print "-d $qossettings{'DIP'} ";
330 }
331 print "-p $qossettings{'PPROT'} ";
332 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
333 print "-m multiport ";
334 }
335 if ($qossettings{'QPORT'} ne ''){
336 print "--sport $qossettings{'QPORT'} ";
337 }
338 if ($qossettings{'DPORT'} ne ''){
339 print "--dport $qossettings{'DPORT'} ";
340 }
341 print "-j RETURN\n\n";
342 }
343 }
344
345 print <<END
346
347 ### SET LEVEL7-RULES
348 END
349 ;
350 foreach $l7ruleentry (sort @l7rules)
351 {
352 @l7ruleline = split( /\;/, $l7ruleentry );
353 if ( $l7ruleline[1] eq $qossettings{'RED_DEV'} )
354 {
355 $qossettings{'CLASS'} = $l7ruleline[0];
356 $qossettings{'DEVICE'} = $l7ruleline[1];
357 $qossettings{'L7PROT'} = $l7ruleline[2];
358 $qossettings{'QIP'} = $l7ruleline[3];
359 $qossettings{'DIP'} = $l7ruleline[4];
360 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
361 if ($qossettings{'QIP'} ne ''){
362 print "-s $qossettings{'QIP'} ";
363 }
364 if ($qossettings{'DIP'} ne ''){
365 print "-d $qossettings{'DIP'} ";
366 }
367 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-mark $qossettings{'CLASS'}\n";
368 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
369 if ($qossettings{'QIP'} ne ''){
370 print "-s $qossettings{'QIP'} ";
371 }
372 if ($qossettings{'DIP'} ne ''){
373 print "-d $qossettings{'DIP'} ";
374 }
375 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j RETURN\n";
376 }
377 }
378
379 print <<END
380
381 ### REDUNDANT: SET ALL NONMARKED PACKETS TO DEFAULT CLASS
382 iptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} -m mark --mark 0 -j MARK --set-mark $qossettings{'DEFCLASS_OUT'}
383
384 ###
385 ### $qossettings{'IMQ_DEV'}
386 ###
387
388 ### BRING UP $qossettings{'IMQ_DEV'}
389 if [ `lsmod | grep -q ipt_IMQ` ]; then
390 insmod ipt_IMQ
391 sleep 2
392 fi
393 modprobe imq numdevs=1
394 ip link set $qossettings{'IMQ_DEV'} up
395
396 ### SET QUEUE LENGTH & MTU - has just to be tested!!! IMPORTANT
397 ip link set dev $qossettings{'IMQ_DEV'} qlen $qossettings{'QLENGTH'}
398 # ip link set dev $qossettings{'IMQ_DEV'} mtu $qossettings{'MTU'}
399
400 ### ADD HTB QDISC FOR $qossettings{'IMQ_DEV'}
401 tc qdisc add dev $qossettings{'IMQ_DEV'} root handle 2: htb default $qossettings{'DEFCLASS_INC'}
402
403 ### MAIN RATE LIMIT
404 tc class add dev $qossettings{'IMQ_DEV'} parent 2: classid 2:1 htb rate $qossettings{'INC_SPD'}kbit
405
406 ### CLASSES FOR $qossettings{'IMQ_DEV'}
407 END
408 ;
409 foreach $classentry (sort @classes)
410 {
411 @classline = split( /\;/, $classentry );
412 if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
413 $qossettings{'DEVICE'} = $classline[0];
414 $qossettings{'CLASS'} = $classline[1];
415 $qossettings{'PRIO'} = $classline[2];
416 $qossettings{'RATE'} = $classline[3];
417 $qossettings{'CEIL'} = $classline[4];
418 $qossettings{'BURST'} = $classline[5];
419 $qossettings{'CBURST'} = $classline[6];
420 print "\ttc class add dev $qossettings{'DEVICE'} parent 2:1 classid 2:$qossettings{'CLASS'} htb rate $qossettings{'RATE'}kbit ceil $qossettings{'CEIL'}kbit prio $qossettings{'PRIO'} ";
421 if (($qossettings{'BURST'} ne '') && ($qossettings{'BURST'} ne 0)) {
422 print "burst $qossettings{'BURST'}k ";
423 }
424 if (($qossettings{'CBURST'} ne '') && ($qossettings{'CBURST'} ne 0)) {
425 print "cburst $qossettings{'CBURST'}k";
426 }
427 print "\n";
428 }
429 }
430 foreach $subclassentry (sort @subclasses) {
431 @subclassline = split( /\;/, $subclassentry );
432 if ($qossettings{'IMQ_DEV'} eq $subclassline[0]) {
433 $qossettings{'DEVICE'} = $subclassline[0];
434 $qossettings{'CLASS'} = $subclassline[1];
435 $qossettings{'SCLASS'} = $subclassline[2];
436 $qossettings{'SPRIO'} = $subclassline[3];
437 $qossettings{'SRATE'} = $subclassline[4];
438 $qossettings{'SCEIL'} = $subclassline[5];
439 $qossettings{'SBURST'} = $subclassline[6];
440 $qossettings{'SCBURST'} = $subclassline[7];
441 print "\ttc class add dev $qossettings{'DEVICE'} parent 2:$qossettings{'CLASS'} classid 2:$qossettings{'SCLASS'} htb rate $qossettings{'SRATE'}kbit ceil $qossettings{'SCEIL'}kbit prio $qossettings{'SPRIO'} ";
442 if ($qossettings{'SBURST'} > 0) {
443 print "burst $qossettings{'SBURST'}k ";
444 }
445 if (($qossettings{'SCBURST'} ne '') && ($qossettings{'SCBURST'} ne 0)) {
446 print "cburst $qossettings{'CBURST'}k";
447 }
448 print "\n";
449 }
450 }
451
452 print "\n\t### ATTACH QDISC TO LEAF CLASSES\n";
453 foreach $classentry (sort @classes)
454 {
455 @classline = split( /\;/, $classentry );
456 if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
457 $qossettings{'DEVICE'} = $classline[0];
458 $qossettings{'CLASS'} = $classline[1];
459 print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 2:$qossettings{'CLASS'} handle $qossettings{'CLASS'}: sfq perturb $qossettings{'SFQ_PERTUB'}\n";
460 }
461 }
462 foreach $subclassentry (sort @subclasses) {
463 @subclassline = split( /\;/, $subclassentry );
464 if ($qossettings{'IMQ_DEV'} eq $subclassline[0]) {
465 $qossettings{'DEVICE'} = $subclassline[0];
466 $qossettings{'SCLASS'} = $subclassline[2];
467 print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 2:$qossettings{'SCLASS'} handle $qossettings{'SCLASS'}: sfq perturb $qossettings{'SFQ_PERTUB'}\n";
468 }
469 }
470 print "\n\t### FILTER TRAFFIC INTO CLASSES\n";
471 foreach $classentry (sort @classes)
472 {
473 @classline = split( /\;/, $classentry );
474 if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
475 $qossettings{'DEVICE'} = $classline[0];
476 $qossettings{'CLASS'} = $classline[1];
477 print "\ttc filter add dev $qossettings{'DEVICE'} parent 2:0 prio 0 protocol ip handle $qossettings{'CLASS'} fw flowid 2:$qossettings{'CLASS'}\n";
478 }
479 }
480 foreach $subclassentry (sort @subclasses) {
481 @subclassline = split( /\;/, $subclassentry );
482 if ($qossettings{'IMQ_DEV'} eq $subclassline[0]) {
483 $qossettings{'DEVICE'} = $subclassline[0];
484 $qossettings{'CLASS'} = $subclassline[1];
485 $qossettings{'SCLASS'} = $subclassline[2];
486 print "\ttc filter add dev $qossettings{'DEVICE'} parent 2:0 prio 0 protocol ip handle $qossettings{'SCLASS'} fw flowid 2:$qossettings{'SCLASS'}\n";
487 }
488 }
489 print <<END
490
491 ### ADD QOS-INC CHAIN TO THE MANGLE TABLE IN IPTABLES
492 iptables -t mangle -N QOS-INC
493 iptables -t mangle -A PREROUTING -i $qossettings{'RED_DEV'} -j IMQ --todev 0
494 iptables -t mangle -I PREROUTING -i $qossettings{'RED_DEV'} -j QOS-INC
495 iptables -t mangle -A PREROUTING -i $qossettings{'RED_DEV'} -j QOS-TOS
496
497 ### SET TOS
498 END
499 ;
500 foreach $tosruleentry (sort @tosrules)
501 {
502 @tosruleline = split( /\;/, $tosruleentry );
503 $qossettings{'CLASS'} = $tosruleline[0];
504 $qossettings{'TOS'} = abs $tosruleline[2] * 2;
505 if ( $tosruleline[1] eq $qossettings{'IMQ_DEV'} )
506 {
507 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} -m tos --tos $qossettings{'TOS'} -j MARK --set-mark $qossettings{'CLASS'}\n";
508 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} -m tos --tos $qossettings{'TOS'} -j RETURN\n";
509 }
510
511 }
512
513 print "\n\t### SET PORT-RULES\n";
514 foreach $portruleentry (sort @portrules)
515 {
516 @portruleline = split( /\;/, $portruleentry );
517 if ( $portruleline[1] eq $qossettings{'IMQ_DEV'} )
518 {
519 $qossettings{'CLASS'} = $portruleline[0];
520 $qossettings{'DEVICE'} = $portruleline[1];
521 $qossettings{'PPROT'} = $portruleline[2];
522 $qossettings{'QIP'} = $portruleline[3];
523 $qossettings{'QPORT'} = $portruleline[4];
524 $qossettings{'DIP'} = $portruleline[5];
525 $qossettings{'DPORT'} = $portruleline[6];
526 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
527 if ($qossettings{'QIP'} ne ''){
528 print "-s $qossettings{'QIP'} ";
529 }
530 if ($qossettings{'DIP'} ne ''){
531 print "-d $qossettings{'DIP'} ";
532 }
533 print "-p $qossettings{'PPROT'} ";
534 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
535 print "-m multiport ";
536 }
537 if ($qossettings{'QPORT'} ne ''){
538 print "--sport $qossettings{'QPORT'} ";
539 }
540 if ($qossettings{'DPORT'} ne ''){
541 print "--dport $qossettings{'DPORT'} ";
542 }
543 print "-j MARK --set-mark $qossettings{'CLASS'}\n";
544 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
545 if ($qossettings{'QIP'} ne ''){
546 print "-s $qossettings{'QIP'} ";
547 }
548 if ($qossettings{'DIP'} ne ''){
549 print "-d $qossettings{'DIP'} ";
550 }
551 print "-p $qossettings{'PPROT'} ";
552 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
553 print "-m multiport ";
554 }
555 if ($qossettings{'QPORT'} ne ''){
556 print "--sport $qossettings{'QPORT'} ";
557 }
558 if ($qossettings{'DPORT'} ne ''){
559 print "--dport $qossettings{'DPORT'} ";
560 }
561 print "-j RETURN\n\n";
562 }
563 }
564
565 print <<END
566
567 ### SET LEVEL7-RULES
568 END
569 ;
570 foreach $l7ruleentry (sort @l7rules)
571 {
572 @l7ruleline = split( /\;/, $l7ruleentry );
573 if ( $l7ruleline[1] eq $qossettings{'IMQ_DEV'} )
574 {
575 $qossettings{'CLASS'} = $l7ruleline[0];
576 $qossettings{'DEVICE'} = $l7ruleline[1];
577 $qossettings{'L7PROT'} = $l7ruleline[2];
578 $qossettings{'QIP'} = $l7ruleline[3];
579 $qossettings{'DIP'} = $l7ruleline[4];
580 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
581 if ($qossettings{'QIP'} ne ''){
582 print "-s $qossettings{'QIP'} ";
583 }
584 if ($qossettings{'DIP'} ne ''){
585 print "-d $qossettings{'DIP'} ";
586 }
587 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-mark $qossettings{'CLASS'}\n";
588 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
589 if ($qossettings{'QIP'} ne ''){
590 print "-s $qossettings{'QIP'} ";
591 }
592 if ($qossettings{'DIP'} ne ''){
593 print "-d $qossettings{'DIP'} ";
594 }
595 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j RETURN\n";
596 }
597 }
598
599 print <<END
600 ### REDUNDANT: SET ALL NONMARKED PACKETS TO DEFAULT CLASS
601 iptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} -m mark --mark 0 -j MARK --set-mark $qossettings{'DEFCLASS_INC'}
602
603 ### SETTING TOS BITS
604 END
605 ;
606 foreach $classentry (sort @classes)
607 {
608 @classline = split( /\;/, $classentry );
609 $qossettings{'CLASS'} = $classline[1];
610 $qossettings{'TOS'} = abs $classline[7] * 2;
611 if ($qossettings{'TOS'} ne "0") {
612 print "\tiptables -t mangle -A QOS-TOS -m mark --mark $qossettings{'CLASS'} -j TOS --set-tos $qossettings{'TOS'}\n";
613 print "\tiptables -t mangle -A QOS-TOS -m mark --mark $qossettings{'CLASS'} -j RETURN\n";
614 }
615 }
616 foreach $subclassentry (sort @subclasses)
617 {
618 @subclassline = split( /\;/, $subclassentry );
619 $qossettings{'SUBCLASS'} = $subclassline[1];
620 $qossettings{'TOS'} = $subclassline[8];
621 $qossettings{'TOS'} = abs $qossettings{'TOS'} * 2;
622 if ($qossettings{'TOS'} ne "0") {
623 print "\tiptables -t mangle -A QOS-TOS -m mark --mark $qossettings{'SUBCLASS'} -j TOS --set-tos $qossettings{'TOS'}\n";
624 print "\tiptables -t mangle -A QOS-TOS -m mark --mark $qossettings{'SUBCLASS'} -j RETURN\n";
625 }
626 }
627
628 print <<END
629
630 ## STARTING COLLECTOR
631 ( sleep 10 && /usr/local/bin/qosd $qossettings{'RED_DEV'} >/dev/null 2>&1) &
632 ( sleep 10 && /usr/local/bin/qosd $qossettings{'IMQ_DEV'} >/dev/null 2>&1) &
633
634 echo "Quality of Service was successfully started!"
635 exit 0
636 ;;
637 clear|stop)
638 ### RESET EVERYTHING TO A KNOWN STATE
639 killall -9 qosd
640 # DELETE QDISCS
641 tc qdisc del dev $qossettings{'RED_DEV'} root
642 tc qdisc del dev $qossettings{'IMQ_DEV'} root
643 # STOP IMQ-DEVICE
644 ip link set $qossettings{'IMQ_DEV'} down
645 iptables -t mangle --delete PREROUTING -i $qossettings{'RED_DEV'} -j IMQ --todev 0
646 rmmod imq
647 # REMOVE & FLUSH CHAINS
648 iptables -t mangle --delete POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-OUT
649 iptables -t mangle --delete POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-TOS
650 iptables -t mangle --flush QOS-OUT
651 iptables -t mangle --delete-chain QOS-OUT
652 iptables -t mangle --delete PREROUTING -i $qossettings{'RED_DEV'} -j QOS-INC
653 iptables -t mangle --delete PREROUTING -i $qossettings{'RED_DEV'} -j QOS-TOS
654 iptables -t mangle --flush QOS-INC
655 iptables -t mangle --delete-chain QOS-INC
656 iptables -t mangle --flush QOS-TOS
657 iptables -t mangle --delete-chain QOS-TOS
658 rmmod sch_htb
659 echo "Quality of Service was successfully cleared!"
660 ;;
661 gen|generate)
662 echo -n "Generateing the QoS-Scripts..."
663 /usr/bin/perl /var/ipfire/qos/bin/makeqosscripts.pl > /var/ipfire/qos/bin/qos.sh
664 echo ".Done!"
665 exit 0
666 ;;
667 restart)
668 ### FIRST CLEAR EVERYTHING
669 \$0 clear
670
671 ### THEN START
672 \$0 start
673 ;;
674 esac
675 ### EOF
676 END
677 ;
678
679 ############################################################################################################################
680 ############################################################################################################################