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 --- config/qos/makeqosscripts.pl | 57 ++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 22 deletions(-)
diff --git a/config/qos/makeqosscripts.pl b/config/qos/makeqosscripts.pl index cbbbf70f8..3af046ac3 100644 --- a/config/qos/makeqosscripts.pl +++ b/config/qos/makeqosscripts.pl @@ -56,6 +56,12 @@ 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'; @@ -74,6 +80,10 @@ $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; @@ -200,9 +210,11 @@ foreach $classentry (sort @classes) 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 handle $qossettings{'CLASS'} fw flowid 1:$qossettings{'CLASS'}\n"; + 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 @@ -213,28 +225,28 @@ print <<END 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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-mark $qossettings{'ACK'} + 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 @@ -247,7 +259,7 @@ END $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-mark $qossettings{'CLASS'}\n"; + 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"; } } @@ -282,7 +294,7 @@ print "\n\t### SET PORT-RULES\n"; if ($qossettings{'DPORT'} ne ''){ print "--dport $qossettings{'DPORT'} "; } - print "-j MARK --set-mark $qossettings{'CLASS'}\n"; + 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'} "; @@ -326,7 +338,7 @@ END if ($qossettings{'DIP'} ne ''){ print "-d $qossettings{'DIP'} "; } - print "-m layer7 --l7dir /etc/l7-protocols/protocols --l7proto $qossettings{'L7PROT'} -j MARK --set-mark $qossettings{'CLASS'}\n"; + 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'} "; @@ -341,7 +353,7 @@ END print <<END
### REDUNDANT: SET ALL NONMARKED PACKETS TO DEFAULT CLASS - iptables -t mangle -A QOS-OUT -m mark --mark 0 -j MARK --set-mark $qossettings{'DEFCLASS_OUT'} + iptables -t mangle -A QOS-OUT -m mark --mark 0/$QOS_OUT_MASK -j MARK --set-xmark $DEF_OUT_MARK
### ### $qossettings{'IMQ_DEV'} @@ -410,7 +422,8 @@ foreach $classentry (sort @classes) 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 handle $qossettings{'CLASS'} fw flowid 2:$qossettings{'CLASS'}\n"; + 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 @@ -420,7 +433,7 @@ print <<END 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 -j RETURN + iptables -t mangle -A QOS-INC -m mark ! --mark 0/$QOS_INC_MASK -j RETURN
### SET TOS END @@ -432,7 +445,7 @@ END $qossettings{'TOS'} = abs $tosruleline[2] * 2; if ( $tosruleline[1] eq $qossettings{'IMQ_DEV'} ) { - print "\tiptables -t mangle -A QOS-INC -m mark --mark 0 -m tos --tos $qossettings{'TOS'} -j MARK --set-mark $qossettings{'CLASS'}\n"; + 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"; }
} @@ -450,7 +463,7 @@ print "\n\t### SET PORT-RULES\n"; $qossettings{'QPORT'} = $portruleline[4]; $qossettings{'DIP'} = $portruleline[5]; $qossettings{'DPORT'} = $portruleline[6]; - print "\tiptables -t mangle -A QOS-INC -m mark --mark 0 "; + print "\tiptables -t mangle -A QOS-INC -m mark --mark 0/$QOS_INC_MASK "; if ($qossettings{'QIP'} ne ''){ print "-s $qossettings{'QIP'} "; } @@ -467,7 +480,7 @@ print "\n\t### SET PORT-RULES\n"; if ($qossettings{'DPORT'} ne ''){ print "--dport $qossettings{'DPORT'} "; } - print "-j MARK --set-mark $qossettings{'CLASS'}\n"; + print "-j MARK --set-xmark " . ($qossettings{'CLASS'} << $QOS_INC_SHIFT) . "/$QOS_INC_MASK\n"; } }
@@ -486,23 +499,23 @@ END $qossettings{'L7PROT'} = $l7ruleline[2]; $qossettings{'QIP'} = $l7ruleline[3]; $qossettings{'DIP'} = $l7ruleline[4]; - print "\tiptables -t mangle -A QOS-INC -m mark --mark 0 "; + 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-mark $qossettings{'CLASS'}\n"; + 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 -m layer7 ! --l7proto unset -j MARK --set-mark $qossettings{'DEFCLASS_INC'} + 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 -j CONNMARK --save-mark + 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