mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-25 10:22:59 +02:00
In order to not deal with any marks from NAT and the IPS, this patch adds masks to all places where packets are being marked for individual QoS classes. Instead of being able to use the "fw" match in tc, we have to use the u32 to apply the mask. Signed-off-by: Michael Tremer <michael.tremer@ipfire.org> Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
582 lines
20 KiB
Perl
582 lines
20 KiB
Perl
#!/usr/bin/perl
|
|
###############################################################################
|
|
# #
|
|
# IPFire.org - A linux based firewall #
|
|
# Copyright (C) 2007-2013 IPFire Team <info@ipfire.org> #
|
|
# #
|
|
# This program is free software: you can redistribute it and/or modify #
|
|
# it under the terms of the GNU General Public License as published by #
|
|
# the Free Software Foundation, either version 3 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
# #
|
|
###############################################################################
|
|
|
|
use strict;
|
|
# enable only the following on debugging purpose
|
|
# use warnings;
|
|
|
|
require '/var/ipfire/general-functions.pl';
|
|
require "${General::swroot}/lang.pl";
|
|
require "${General::swroot}/header.pl";
|
|
|
|
my %qossettings = ();
|
|
my %checked = ();
|
|
my %netsettings = ();
|
|
my $message = "";
|
|
my $errormessage = "";
|
|
my $c = "";
|
|
my $direntry = "";
|
|
my $classentry = "";
|
|
my $l7ruleentry = "";
|
|
my $portruleentry = "";
|
|
my $tosruleentry = "";
|
|
my @tmp = ();
|
|
my @classes = ();
|
|
my @l7rules = ();
|
|
my @portrules = ();
|
|
my @tosrules = ();
|
|
my @tmpline = ();
|
|
my @classline = ();
|
|
my @tosruleline = ();
|
|
my @l7ruleline = ();
|
|
my @portruleline = ();
|
|
my @proto = ();
|
|
my %selected= () ;
|
|
my $classfile = "/var/ipfire/qos/classes";
|
|
my $level7file = "/var/ipfire/qos/level7config";
|
|
my $portfile = "/var/ipfire/qos/portconfig";
|
|
my $tosfile = "/var/ipfire/qos/tosconfig";
|
|
my $fqcodel_options = "limit 10240 quantum 1514";
|
|
|
|
# Define iptables MARKs
|
|
my $QOS_INC_MASK = 0x0000ff00;
|
|
my $QOS_INC_SHIFT = 8;
|
|
my $QOS_OUT_MASK = 0x000000ff;
|
|
my $QOS_OUT_SHIFT = 0;
|
|
|
|
&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
|
|
|
|
$qossettings{'ENABLED'} = 'off';
|
|
$qossettings{'EDIT'} = 'no';
|
|
$qossettings{'OUT_SPD'} = '';
|
|
$qossettings{'INC_SPD'} = '';
|
|
$qossettings{'DEF_OUT_SPD'} = '';
|
|
$qossettings{'DEF_INC_SPD'} = '';
|
|
$qossettings{'DEFCLASS_INC'} = '';
|
|
$qossettings{'DEFCLASS_OUT'} = '';
|
|
$qossettings{'ACK'} = '';
|
|
$qossettings{'RED_DEV'} = `cat /var/ipfire/red/iface`;
|
|
$qossettings{'IMQ_DEV'} = 'imq0';
|
|
$qossettings{'TOS'} = '';
|
|
$qossettings{'VALID'} = 'yes';
|
|
|
|
&General::readhash("${General::swroot}/qos/settings", \%qossettings);
|
|
|
|
my $ACK_MARK = ($qossettings{'ACK'} << $QOS_OUT_SHIFT) . "/$QOS_OUT_MASK";
|
|
my $DEF_OUT_MARK = ($qossettings{'DEFCLASS_OUT'} << $QOS_OUT_SHIFT) . "/$QOS_OUT_MASK";
|
|
my $DEF_INC_MARK = ($qossettings{'DEFCLASS_INC'} << $QOS_INC_SHIFT) . "/$QOS_INC_MASK";
|
|
|
|
open( FILE, "< $classfile" ) or die "Unable to read $classfile";
|
|
@classes = <FILE>;
|
|
close FILE;
|
|
open( FILE, "< $level7file" ) or die "Unable to read $level7file";
|
|
@l7rules = <FILE>;
|
|
close FILE;
|
|
open( FILE, "< $portfile" ) or die "Unable to read $portfile";
|
|
@portrules = <FILE>;
|
|
close FILE;
|
|
open( FILE, "< $tosfile" ) or die "Unable to read $tosfile";
|
|
@tosrules = <FILE>;
|
|
close FILE;
|
|
|
|
############################################################################################################################
|
|
############################################################################################################################
|
|
|
|
print <<END
|
|
#/bin/bash
|
|
#################################################
|
|
# This is an autocreated QoS-Script for #
|
|
# IPFIRE #
|
|
# Copyright by the IPFire Team (GPLv2) #
|
|
# www.ipfire.org #
|
|
#################################################
|
|
|
|
### SYSTEMVARIABLES:
|
|
# RED INTERFACE: $qossettings{'RED_DEV'}
|
|
# IMQ DEVICE: $qossettings{'IMQ_DEV'}
|
|
|
|
eval \$(/usr/local/bin/readhash /var/ipfire/main/settings)
|
|
if [ "\$RRDLOG" == "" ]; then
|
|
RRDLOG=/var/log/rrd
|
|
fi
|
|
|
|
case "\$1" in
|
|
|
|
status)
|
|
case "\$2" in
|
|
qdisc)
|
|
echo "[qdisc]"
|
|
tc -s qdisc show dev $qossettings{'RED_DEV'}
|
|
tc -s qdisc show dev $qossettings{'IMQ_DEV'}
|
|
exit 0
|
|
;;
|
|
class)
|
|
echo "[class]"
|
|
tc -s class show dev $qossettings{'RED_DEV'}
|
|
tc -s class show dev $qossettings{'IMQ_DEV'}
|
|
exit 0
|
|
;;
|
|
filter)
|
|
echo "[filter]"
|
|
tc -s filter show dev $qossettings{'RED_DEV'}
|
|
tc -s filter show dev $qossettings{'IMQ_DEV'}
|
|
exit 0
|
|
;;
|
|
iptables)
|
|
echo "[iptables]"
|
|
iptables -t mangle -n -L QOS-OUT -v -x 2> /dev/null
|
|
iptables -t mangle -n -L QOS-INC -v -x 2> /dev/null
|
|
exit 0
|
|
;;
|
|
esac
|
|
\$0 \$1 qdisc
|
|
\$0 \$1 class
|
|
\$0 \$1 filter
|
|
\$0 \$1 iptables
|
|
exit 0
|
|
;;
|
|
start)
|
|
###
|
|
### $qossettings{'RED_DEV'}
|
|
###
|
|
|
|
### INIT KERNEL
|
|
modprobe sch_htb
|
|
|
|
### ADD HTB QDISC FOR $qossettings{'RED_DEV'}
|
|
tc qdisc del dev $qossettings{'RED_DEV'} root >/dev/null 2>&1
|
|
tc qdisc add dev $qossettings{'RED_DEV'} root handle 1: htb default $qossettings{'DEFCLASS_OUT'}
|
|
|
|
### MAIN RATE LIMIT
|
|
tc class add dev $qossettings{'RED_DEV'} parent 1: classid 1:1 htb rate $qossettings{'OUT_SPD'}kbit
|
|
|
|
### CLASSES FOR $qossettings{'RED_DEV'}
|
|
END
|
|
;
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'RED_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
$qossettings{'PRIO'} = $classline[2];
|
|
$qossettings{'RATE'} = $classline[3];
|
|
$qossettings{'CEIL'} = $classline[4];
|
|
$qossettings{'BURST'} = $classline[5];
|
|
$qossettings{'CBURST'} = $classline[6];
|
|
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'} ";
|
|
if (($qossettings{'BURST'} ne '') && ($qossettings{'BURST'} ne 0)) {
|
|
print "burst $qossettings{'BURST'}k ";
|
|
}
|
|
if (($qossettings{'CBURST'} ne '') && ($qossettings{'CBURST'} ne 0)) {
|
|
print "cburst $qossettings{'CBURST'}k";
|
|
}
|
|
print "\n";
|
|
}
|
|
}
|
|
|
|
print "\n\t### ATTACH QDISC TO LEAF CLASSES\n";
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'RED_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 1:$qossettings{'CLASS'} handle $qossettings{'CLASS'}: fq_codel $fqcodel_options\n";
|
|
}
|
|
}
|
|
print "\n\t### FILTER TRAFFIC INTO CLASSES\n";
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'RED_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
print "\ttc filter add dev $qossettings{'DEVICE'} parent 1:0 prio 0 protocol ip";
|
|
printf(" u32 match mark 0x%x 0x%x flowid 1:%d\n", ($qossettings{'CLASS'} << $QOS_OUT_SHIFT), $QOS_OUT_MASK, $qossettings{'CLASS'});
|
|
}
|
|
}
|
|
|
|
print <<END
|
|
|
|
### ADD QOS-OUT CHAIN TO THE MANGLE TABLE IN IPTABLES
|
|
iptables -t mangle -N QOS-OUT
|
|
iptables -t mangle -I POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-OUT
|
|
|
|
### Don't change mark on traffic for the ipsec tunnel
|
|
iptables -t mangle -A QOS-OUT -m mark --mark 50 -j RETURN
|
|
|
|
### MARK ACKs
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags SYN,RST SYN -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags SYN,RST SYN -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p icmp -m length --length 40:100 -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p icmp -m length --length 40:100 -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --syn -m length --length 40:68 -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --syn -m length --length 40:68 -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK -m length --length 40:100 -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK -m length --length 40:100 -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL RST -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL RST -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK,RST -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK,RST -j RETURN
|
|
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK,FIN -j MARK --set-xmark $ACK_MARK
|
|
iptables -t mangle -A QOS-OUT -p tcp --tcp-flags ALL ACK,FIN -j RETURN
|
|
|
|
### SET TOS
|
|
END
|
|
;
|
|
foreach $tosruleentry (sort @tosrules)
|
|
{
|
|
@tosruleline = split( /\;/, $tosruleentry );
|
|
$qossettings{'CLASS'} = $tosruleline[0];
|
|
$qossettings{'TOS'} = abs $tosruleline[2] * 2;
|
|
if ( $tosruleline[1] eq $qossettings{'RED_DEV'} )
|
|
{
|
|
print "\tiptables -t mangle -A QOS-OUT -m tos --tos $qossettings{'TOS'} -j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_OUT_SHIFT) . "/$QOS_OUT_MASK\n";
|
|
print "\tiptables -t mangle -A QOS-OUT -m tos --tos $qossettings{'TOS'} -j RETURN\n";
|
|
}
|
|
}
|
|
|
|
print "\n\t### SET PORT-RULES\n";
|
|
foreach $portruleentry (sort @portrules)
|
|
{
|
|
@portruleline = split( /\;/, $portruleentry );
|
|
if ( $portruleline[1] eq $qossettings{'RED_DEV'} )
|
|
{
|
|
$qossettings{'CLASS'} = $portruleline[0];
|
|
$qossettings{'DEVICE'} = $portruleline[1];
|
|
$qossettings{'PPROT'} = $portruleline[2];
|
|
$qossettings{'QIP'} = $portruleline[3];
|
|
$qossettings{'QPORT'} = $portruleline[4];
|
|
$qossettings{'DIP'} = $portruleline[5];
|
|
$qossettings{'DPORT'} = $portruleline[6];
|
|
print "\tiptables -t mangle -A QOS-OUT ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-p $qossettings{'PPROT'} ";
|
|
# if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
|
|
# print "-m multiport ";
|
|
# }
|
|
if ($qossettings{'QPORT'} ne ''){
|
|
print "--sport $qossettings{'QPORT'} ";
|
|
}
|
|
if ($qossettings{'DPORT'} ne ''){
|
|
print "--dport $qossettings{'DPORT'} ";
|
|
}
|
|
print "-j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_OUT_SHIFT) . "/$QOS_OUT_MASK\n";
|
|
print "\tiptables -t mangle -A QOS-OUT ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-p $qossettings{'PPROT'} ";
|
|
# if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
|
|
# print "-m multiport ";
|
|
# }
|
|
if ($qossettings{'QPORT'} ne ''){
|
|
print "--sport $qossettings{'QPORT'} ";
|
|
}
|
|
if ($qossettings{'DPORT'} ne ''){
|
|
print "--dport $qossettings{'DPORT'} ";
|
|
}
|
|
print "-j RETURN\n\n";
|
|
}
|
|
}
|
|
|
|
print <<END
|
|
|
|
### SET LEVEL7-RULES
|
|
END
|
|
;
|
|
foreach $l7ruleentry (sort @l7rules)
|
|
{
|
|
@l7ruleline = split( /\;/, $l7ruleentry );
|
|
if ( $l7ruleline[1] eq $qossettings{'RED_DEV'} )
|
|
{
|
|
$qossettings{'CLASS'} = $l7ruleline[0];
|
|
$qossettings{'DEVICE'} = $l7ruleline[1];
|
|
$qossettings{'L7PROT'} = $l7ruleline[2];
|
|
$qossettings{'QIP'} = $l7ruleline[3];
|
|
$qossettings{'DIP'} = $l7ruleline[4];
|
|
print "\tiptables -t mangle -A QOS-OUT ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-xmark " . $qossettings{'CLASS'} << $QOS_OUT_SHIFT . "/$QOS_OUT_MASK\n";
|
|
print "\tiptables -t mangle -A QOS-OUT ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j RETURN\n";
|
|
}
|
|
}
|
|
|
|
print <<END
|
|
|
|
### REDUNDANT: SET ALL NONMARKED PACKETS TO DEFAULT CLASS
|
|
iptables -t mangle -A QOS-OUT -m mark --mark 0/$QOS_OUT_MASK -j MARK --set-xmark $DEF_OUT_MARK
|
|
|
|
###
|
|
### $qossettings{'IMQ_DEV'}
|
|
###
|
|
|
|
tc qdisc del dev $qossettings{'RED_DEV'} ingress >/dev/null 2>&1
|
|
tc qdisc add dev $qossettings{'RED_DEV'} handle ffff: ingress
|
|
|
|
### BRING UP $qossettings{'IMQ_DEV'}
|
|
if [ ! -d "/sys/class/net/$qossettings{'IMQ_DEV'}" ]; then
|
|
ip link add name $qossettings{'IMQ_DEV'} type ifb
|
|
fi
|
|
|
|
ip link set $qossettings{'IMQ_DEV'} up
|
|
|
|
tc filter add dev $qossettings{'RED_DEV'} parent ffff: protocol all u32 match u32 0 0 \\
|
|
action connmark \\
|
|
action mirred egress redirect dev $qossettings{'IMQ_DEV'}
|
|
|
|
### ADD HTB QDISC FOR $qossettings{'IMQ_DEV'}
|
|
tc qdisc del dev $qossettings{'IMQ_DEV'} root >/dev/null 2>&1
|
|
tc qdisc add dev $qossettings{'IMQ_DEV'} root handle 2: htb default $qossettings{'DEFCLASS_INC'}
|
|
|
|
### MAIN RATE LIMIT
|
|
tc class add dev $qossettings{'IMQ_DEV'} parent 2: classid 2:1 htb rate $qossettings{'INC_SPD'}kbit
|
|
|
|
### CLASSES FOR $qossettings{'IMQ_DEV'}
|
|
END
|
|
;
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
$qossettings{'PRIO'} = $classline[2];
|
|
$qossettings{'RATE'} = $classline[3];
|
|
$qossettings{'CEIL'} = $classline[4];
|
|
$qossettings{'BURST'} = $classline[5];
|
|
$qossettings{'CBURST'} = $classline[6];
|
|
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'} ";
|
|
if (($qossettings{'BURST'} ne '') && ($qossettings{'BURST'} ne 0)) {
|
|
print "burst $qossettings{'BURST'}k ";
|
|
}
|
|
if (($qossettings{'CBURST'} ne '') && ($qossettings{'CBURST'} ne 0)) {
|
|
print "cburst $qossettings{'CBURST'}k";
|
|
}
|
|
print "\n";
|
|
}
|
|
}
|
|
|
|
print "\n\t### ATTACH QDISC TO LEAF CLASSES\n";
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
print "\ttc qdisc add dev $qossettings{'DEVICE'} parent 2:$qossettings{'CLASS'} handle $qossettings{'CLASS'}: fq_codel $fqcodel_options\n";
|
|
}
|
|
}
|
|
print "\n\t### FILTER TRAFFIC INTO CLASSES\n";
|
|
foreach $classentry (sort @classes)
|
|
{
|
|
@classline = split( /\;/, $classentry );
|
|
if ($qossettings{'IMQ_DEV'} eq $classline[0]) {
|
|
$qossettings{'DEVICE'} = $classline[0];
|
|
$qossettings{'CLASS'} = $classline[1];
|
|
print "\ttc filter add dev $qossettings{'DEVICE'} parent 2:0 prio 0 protocol ip";
|
|
printf(" u32 match mark 0x%x 0x%x flowid 2:%d\n", ($qossettings{'CLASS'} << $QOS_INC_SHIFT), $QOS_INC_MASK, $qossettings{'CLASS'});
|
|
}
|
|
}
|
|
print <<END
|
|
|
|
### ADD QOS-INC CHAIN TO THE MANGLE TABLE IN IPTABLES
|
|
iptables -t mangle -N QOS-INC
|
|
iptables -t mangle -A PREROUTING -i $qossettings{'RED_DEV'} -j QOS-INC
|
|
|
|
# If the packet is already marked, then skip the processing
|
|
iptables -t mangle -A QOS-INC -m mark ! --mark 0/$QOS_INC_MASK -j RETURN
|
|
|
|
### SET TOS
|
|
END
|
|
;
|
|
foreach $tosruleentry (sort @tosrules)
|
|
{
|
|
@tosruleline = split( /\;/, $tosruleentry );
|
|
$qossettings{'CLASS'} = $tosruleline[0];
|
|
$qossettings{'TOS'} = abs $tosruleline[2] * 2;
|
|
if ( $tosruleline[1] eq $qossettings{'IMQ_DEV'} )
|
|
{
|
|
print "\tiptables -t mangle -A QOS-INC -m tos --tos $qossettings{'TOS'} -j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_INC_SHIFT) . "/$QOS_INC_MASK\n";
|
|
}
|
|
|
|
}
|
|
|
|
print "\n\t### SET PORT-RULES\n";
|
|
foreach $portruleentry (sort @portrules)
|
|
{
|
|
@portruleline = split( /\;/, $portruleentry );
|
|
if ( $portruleline[1] eq $qossettings{'IMQ_DEV'} )
|
|
{
|
|
$qossettings{'CLASS'} = $portruleline[0];
|
|
$qossettings{'DEVICE'} = $portruleline[1];
|
|
$qossettings{'PPROT'} = $portruleline[2];
|
|
$qossettings{'QIP'} = $portruleline[3];
|
|
$qossettings{'QPORT'} = $portruleline[4];
|
|
$qossettings{'DIP'} = $portruleline[5];
|
|
$qossettings{'DPORT'} = $portruleline[6];
|
|
print "\tiptables -t mangle -A QOS-INC -m mark --mark 0/$QOS_INC_MASK ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-p $qossettings{'PPROT'} ";
|
|
# if (($qossettings{'QPORT'} ne '') || ($qossettings{'DPORT'} ne '')){
|
|
# print "-m multiport ";
|
|
# }
|
|
if ($qossettings{'QPORT'} ne ''){
|
|
print "--sport $qossettings{'QPORT'} ";
|
|
}
|
|
if ($qossettings{'DPORT'} ne ''){
|
|
print "--dport $qossettings{'DPORT'} ";
|
|
}
|
|
print "-j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_INC_SHIFT) . "/$QOS_INC_MASK\n";
|
|
}
|
|
}
|
|
|
|
print <<END
|
|
|
|
### SET LEVEL7-RULES
|
|
END
|
|
;
|
|
foreach $l7ruleentry (sort @l7rules)
|
|
{
|
|
@l7ruleline = split( /\;/, $l7ruleentry );
|
|
if ( $l7ruleline[1] eq $qossettings{'IMQ_DEV'} )
|
|
{
|
|
$qossettings{'CLASS'} = $l7ruleline[0];
|
|
$qossettings{'DEVICE'} = $l7ruleline[1];
|
|
$qossettings{'L7PROT'} = $l7ruleline[2];
|
|
$qossettings{'QIP'} = $l7ruleline[3];
|
|
$qossettings{'DIP'} = $l7ruleline[4];
|
|
print "\tiptables -t mangle -A QOS-INC -m mark --mark 0/$QOS_INC_MASK ";
|
|
if ($qossettings{'QIP'} ne ''){
|
|
print "-s $qossettings{'QIP'} ";
|
|
}
|
|
if ($qossettings{'DIP'} ne ''){
|
|
print "-d $qossettings{'DIP'} ";
|
|
}
|
|
print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_INC_SHIFT) . "/$QOS_INC_MASK\n";
|
|
}
|
|
}
|
|
|
|
print <<END
|
|
### REDUNDANT: SET ALL NONMARKED PACKETS TO DEFAULT CLASS
|
|
iptables -t mangle -A QOS-INC -m mark --mark 0/$QOS_INC_MASK -m layer7 ! --l7proto unset -j MARK --set-xmark $DEF_INC_MARK
|
|
|
|
# Save mark in connection tracking
|
|
iptables -t mangle -A QOS-INC -m mark --mark 0/$QOS_INC_MASK -j CONNMARK --save-mark
|
|
|
|
## STARTING COLLECTOR
|
|
/usr/local/bin/qosd $qossettings{'RED_DEV'} >/dev/null 2>&1
|
|
/usr/local/bin/qosd $qossettings{'IMQ_DEV'} >/dev/null 2>&1
|
|
|
|
for i in \$(ls \$RRDLOG/class_*.rrd); do
|
|
rrdtool update \$i \$(date +%s): 2>/dev/null
|
|
done
|
|
|
|
echo "Quality of Service was successfully started!"
|
|
exit 0
|
|
;;
|
|
clear|stop)
|
|
### RESET EVERYTHING TO A KNOWN STATE
|
|
killall qosd >/dev/null 2>&1
|
|
|
|
# DELETE QDISCS
|
|
tc qdisc del dev $qossettings{'RED_DEV'} root >/dev/null 2>&1
|
|
tc qdisc del dev $qossettings{'RED_DEV'} ingress >/dev/null 2>&1
|
|
tc qdisc add root dev $qossettings{'RED_DEV'} fq_codel >/dev/null 2>&1
|
|
tc qdisc del dev $qossettings{'IMQ_DEV'} root >/dev/null 2>&1
|
|
tc qdisc del dev $qossettings{'IMQ_DEV'} ingress >/dev/null 2>&1
|
|
tc qdisc add root dev $qossettings{'IMQ_DEV'} fq_codel >/dev/null 2>&1
|
|
# STOP IMQ-DEVICE
|
|
ip link set $qossettings{'IMQ_DEV'} down >/dev/null 2>&1
|
|
ip link del $qossettings{'IMQ_DEV'} >/dev/null 2>&1
|
|
|
|
# REMOVE & FLUSH CHAINS
|
|
iptables -t mangle --delete POSTROUTING -o $qossettings{'RED_DEV'} -j QOS-OUT >/dev/null 2>&1
|
|
iptables -t mangle --delete PREROUTING -i $qossettings{'RED_DEV'} -j QOS-INC >/dev/null 2>&1
|
|
iptables -t mangle --flush QOS-OUT >/dev/null 2>&1
|
|
iptables -t mangle --delete-chain QOS-OUT >/dev/null 2>&1
|
|
iptables -t mangle --flush QOS-INC >/dev/null 2>&1
|
|
iptables -t mangle --delete-chain QOS-INC >/dev/null 2>&1
|
|
|
|
rmmod sch_htb >/dev/null 2>&1
|
|
|
|
for i in \$(ls \$RRDLOG/class_*.rrd); do
|
|
rrdtool update \$i \$(date +%s):
|
|
done
|
|
|
|
echo "Quality of Service was successfully cleared!"
|
|
;;
|
|
gen|generate)
|
|
echo -n "Generating the QoS-Scripts..."
|
|
/usr/bin/perl /var/ipfire/qos/bin/makeqosscripts.pl > /var/ipfire/qos/bin/qos.sh
|
|
echo ".Done!"
|
|
exit 0
|
|
;;
|
|
restart)
|
|
### FIRST CLEAR EVERYTHING
|
|
\$0 clear
|
|
|
|
### THEN START
|
|
\$0 start
|
|
;;
|
|
esac
|
|
### EOF
|
|
END
|
|
;
|
|
|
|
############################################################################################################################
|
|
############################################################################################################################
|