public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Michael Tremer <michael.tremer@ipfire.org>
To: development@lists.ipfire.org
Subject: [PATCH 2/6] QoS: Use the two right hand bytes to mark packets
Date: Mon, 04 Oct 2021 18:52:18 +0100	[thread overview]
Message-ID: <20211004175222.9208-2-michael.tremer@ipfire.org> (raw)
In-Reply-To: <20211004175222.9208-1-michael.tremer@ipfire.org>

[-- Attachment #1: Type: text/plain, Size: 10064 bytes --]

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(a)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
-- 
2.31.0


  reply	other threads:[~2021-10-04 17:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-04 17:52 [PATCH 1/6] firewall: Only check relevant bits for NAT fix rules Michael Tremer
2021-10-04 17:52 ` Michael Tremer [this message]
2021-10-04 17:52 ` [PATCH 3/6] firewall: Always restore all connection marks Michael Tremer
2021-10-04 17:52 ` [PATCH 4/6] QoS: Drop support for hardcoded ACK rules Michael Tremer
2021-10-04 17:52 ` [PATCH 5/6] QoS: Make outgoing packet processing use CONNMARK Michael Tremer
2021-10-04 17:52 ` [PATCH 6/6] IPsec: Replace MARK 50 by 0x00800000 Michael Tremer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211004175222.9208-2-michael.tremer@ipfire.org \
    --to=michael.tremer@ipfire.org \
    --cc=development@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox