]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - config/qos/makeqosscripts.pl
25f0f051029352a4d10fcc2a1bb08f7af9348017
[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 <<END
294
295 ### SET LEVEL7-RULES
296 END
297 ;
298 foreach $l7ruleentry (sort @l7rules)
299 {
300 @l7ruleline = split( /\;/, $l7ruleentry );
301 if ( $l7ruleline[1] eq $qossettings{'RED_DEV'} )
302 {
303 $qossettings{'CLASS'} = $l7ruleline[0];
304 $qossettings{'DEVICE'} = $l7ruleline[1];
305 $qossettings{'L7PROT'} = $l7ruleline[2];
306 $qossettings{'QIP'} = $l7ruleline[3];
307 $qossettings{'DIP'} = $l7ruleline[4];
308 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
309 if ($qossettings{'QIP'} ne ''){
310 print "-s $qossettings{'QIP'} ";
311 }
312 if ($qossettings{'DIP'} ne ''){
313 print "-d $qossettings{'DIP'} ";
314 }
315 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-mark $qossettings{'CLASS'}\n";
316 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
317 if ($qossettings{'QIP'} ne ''){
318 print "-s $qossettings{'QIP'} ";
319 }
320 if ($qossettings{'DIP'} ne ''){
321 print "-d $qossettings{'DIP'} ";
322 }
323 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j RETURN\n";
324 }
325 }
326
327 print "\n\t### SET PORT-RULES\n";
328 foreach $portruleentry (sort @portrules)
329 {
330 @portruleline = split( /\;/, $portruleentry );
331 if ( $portruleline[1] eq $qossettings{'RED_DEV'} )
332 {
333 $qossettings{'CLASS'} = $portruleline[0];
334 $qossettings{'DEVICE'} = $portruleline[1];
335 $qossettings{'PPROT'} = $portruleline[2];
336 $qossettings{'QIP'} = $portruleline[3];
337 $qossettings{'QPORT'} = $portruleline[4];
338 $qossettings{'DIP'} = $portruleline[5];
339 $qossettings{'DPORT'} = $portruleline[6];
340 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
341 if ($qossettings{'QIP'} ne ''){
342 print "-s $qossettings{'QIP'} ";
343 }
344 if ($qossettings{'DIP'} ne ''){
345 print "-d $qossettings{'DIP'} ";
346 }
347 print "-p $qossettings{'PPROT'} ";
348 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
349 print "-m multiport ";
350 }
351 if ($qossettings{'QPORT'} ne ''){
352 print "--sport $qossettings{'QPORT'} ";
353 }
354 if ($qossettings{'DPORT'} ne ''){
355 print "--dport $qossettings{'DPORT'} ";
356 }
357 print "-j MARK --set-mark $qossettings{'CLASS'}\n";
358 print "\tiptables -t mangle -A QOS-OUT -o $qossettings{'RED_DEV'} ";
359 if ($qossettings{'QIP'} ne ''){
360 print "-s $qossettings{'QIP'} ";
361 }
362 if ($qossettings{'DIP'} ne ''){
363 print "-d $qossettings{'DIP'} ";
364 }
365 print "-p $qossettings{'PPROT'} ";
366 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
367 print "-m multiport ";
368 }
369 if ($qossettings{'QPORT'} ne ''){
370 print "--sport $qossettings{'QPORT'} ";
371 }
372 if ($qossettings{'DPORT'} ne ''){
373 print "--dport $qossettings{'DPORT'} ";
374 }
375 print "-j RETURN\n\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 <<END
514
515 ### SET LEVEL7-RULES
516 END
517 ;
518 foreach $l7ruleentry (sort @l7rules)
519 {
520 @l7ruleline = split( /\;/, $l7ruleentry );
521 if ( $l7ruleline[1] eq $qossettings{'IMQ_DEV'} )
522 {
523 $qossettings{'CLASS'} = $l7ruleline[0];
524 $qossettings{'DEVICE'} = $l7ruleline[1];
525 $qossettings{'L7PROT'} = $l7ruleline[2];
526 $qossettings{'QIP'} = $l7ruleline[3];
527 $qossettings{'DIP'} = $l7ruleline[4];
528 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
529 if ($qossettings{'QIP'} ne ''){
530 print "-s $qossettings{'QIP'} ";
531 }
532 if ($qossettings{'DIP'} ne ''){
533 print "-d $qossettings{'DIP'} ";
534 }
535 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-mark $qossettings{'CLASS'}\n";
536 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
537 if ($qossettings{'QIP'} ne ''){
538 print "-s $qossettings{'QIP'} ";
539 }
540 if ($qossettings{'DIP'} ne ''){
541 print "-d $qossettings{'DIP'} ";
542 }
543 print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j RETURN\n";
544 }
545 }
546
547 print "\n\t### SET PORT-RULES\n";
548 foreach $portruleentry (sort @portrules)
549 {
550 @portruleline = split( /\;/, $portruleentry );
551 if ( $portruleline[1] eq $qossettings{'IMQ_DEV'} )
552 {
553 $qossettings{'CLASS'} = $portruleline[0];
554 $qossettings{'DEVICE'} = $portruleline[1];
555 $qossettings{'PPROT'} = $portruleline[2];
556 $qossettings{'QIP'} = $portruleline[3];
557 $qossettings{'QPORT'} = $portruleline[4];
558 $qossettings{'DIP'} = $portruleline[5];
559 $qossettings{'DPORT'} = $portruleline[6];
560 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
561 if ($qossettings{'QIP'} ne ''){
562 print "-s $qossettings{'QIP'} ";
563 }
564 if ($qossettings{'DIP'} ne ''){
565 print "-d $qossettings{'DIP'} ";
566 }
567 print "-p $qossettings{'PPROT'} ";
568 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
569 print "-m multiport ";
570 }
571 if ($qossettings{'QPORT'} ne ''){
572 print "--sport $qossettings{'QPORT'} ";
573 }
574 if ($qossettings{'DPORT'} ne ''){
575 print "--dport $qossettings{'DPORT'} ";
576 }
577 print "-j MARK --set-mark $qossettings{'CLASS'}\n";
578 print "\tiptables -t mangle -A QOS-INC -i $qossettings{'RED_DEV'} ";
579 if ($qossettings{'QIP'} ne ''){
580 print "-s $qossettings{'QIP'} ";
581 }
582 if ($qossettings{'DIP'} ne ''){
583 print "-d $qossettings{'DIP'} ";
584 }
585 print "-p $qossettings{'PPROT'} ";
586 if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
587 print "-m multiport ";
588 }
589 if ($qossettings{'QPORT'} ne ''){
590 print "--sport $qossettings{'QPORT'} ";
591 }
592 if ($qossettings{'DPORT'} ne ''){
593 print "--dport $qossettings{'DPORT'} ";
594 }
595 print "-j RETURN\n\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 /usr/local/bin/qosd $qossettings{'RED_DEV'} >/dev/null 2>&1
632 /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 ############################################################################################################################