[OpenWrt-Devel] [PATCH] qos-scripts: Add IPv6 support

Michael Marley michael at michaelmarley.com
Thu Jan 21 22:45:07 EST 2016


I apologize, my client mangled my previous attempt at resubmission.

Here is an updated version with three improvements.  The problem with
the rules not being removed (which was not new and actually caused by a
grep command incompatible with musl) was fixed by using an updated grep
command (thanks nbd!).  The problems pertaining to the xtables lock
(including "too many links" and "directory not empty") were fixed by
always executing ip[6]tables with the "-w" command-line argument to make
it wait for the xtables lock.  Lastly, I fixed a place where I hardcoded
"iptables" and "ip6tables" instead of looping over the array like
everywhere else.
--trim here--

This adds IPv6 support to qos-scripts for both tc/qdisc and the
iptables classification rules.  The tc/qdisc part is accomplished
by removing "protocol ip" from the tc command line, causing the
rule to be applied to all protocols.  The iptables part is
accomplished by adding each rule using both iptables and ip6tables.

This patch is based on previous work by Ilkka Ollakka and
Dominique Martinet.

Signed-off-by: Michael Marley <michael at michaelmarley.com>
---
 .../qos-scripts/files/usr/lib/qos/generate.sh      | 90 +++++++++++++++-------
 .../qos-scripts/files/usr/lib/qos/tcrules.awk      |  2 +-
 2 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
index caa1125..4a39411 100755
--- a/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
+++ b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
@@ -336,11 +336,11 @@ tc class add dev $dev parent 1: classid 1:1 hfsc sc rate ${rate}kbit ul rate ${r
 	if [ -n "$halfduplex" ]; then
 		export dev_up="tc qdisc del dev $device root >&- 2>&-
 tc qdisc add dev $device root handle 1: hfsc
-tc filter add dev $device parent 1: protocol ip prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb$ifbdev"
+tc filter add dev $device parent 1: prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb$ifbdev"
 	elif [ -n "$download" ]; then
 		append dev_${dir} "tc qdisc del dev $device ingress >&- 2>&-
 tc qdisc add dev $device ingress
-tc filter add dev $device parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb$ifbdev" "$N"
+tc filter add dev $device parent ffff: prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb$ifbdev" "$N"
 	fi
 	add_insmod cls_fw
 	add_insmod sch_hfsc
@@ -397,17 +397,23 @@ start_cg() {
 	local pktrules
 	local sizerules
 	enum_classes "$cg"
-	add_rules iptrules "$ctrules" "iptables -t mangle -A qos_${cg}_ct"
+	for command in $iptables; do
+		add_rules iptrules "$ctrules" "$command -w -t mangle -A qos_${cg}_ct"
+	done
 	config_get classes "$cg" classes
 	for class in $classes; do
 		config_get mark "$class" classnr
 		config_get maxsize "$class" maxsize
 		[ -z "$maxsize" -o -z "$mark" ] || {
 			add_insmod xt_length
-			append pktrules "iptables -t mangle -A qos_${cg} -m mark --mark $mark/0x0f -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N"
+			for command in $iptables; do
+				append pktrules "$command -w -t mangle -A qos_${cg} -m mark --mark $mark/0x0f -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N"
+			done
 		}
 	done
-	add_rules pktrules "$rules" "iptables -t mangle -A qos_${cg}"
+	for command in $iptables; do
+		add_rules pktrules "$rules" "$command -w -t mangle -A qos_${cg}"
+	done
 	for iface in $INTERFACES; do
 		config_get classgroup "$iface" classgroup
 		config_get device "$iface" device
@@ -416,18 +422,40 @@ start_cg() {
 		config_get download "$iface" download
 		config_get halfduplex "$iface" halfduplex
 		download="${download:-${halfduplex:+$upload}}"
-		append up "iptables -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N"
-		append up "iptables -t mangle -A FORWARD -o $device -j qos_${cg}" "$N"
+		for command in $iptables; do
+			append up "$command -w -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N"
+			append up "$command -w -t mangle -A FORWARD -o $device -j qos_${cg}" "$N"
+		done
 	done
 	cat <<EOF
 $INSMOD
-iptables -t mangle -N qos_${cg} >&- 2>&-
-iptables -t mangle -N qos_${cg}_ct >&- 2>&-
-${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff}
-iptables -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0x0f
-iptables -t mangle -A qos_${cg} -m mark --mark 0/0x0f -j qos_${cg}_ct
+EOF
+  
+for command in $iptables; do
+	cat <<EOF
+	$command -w -t mangle -N qos_${cg} 
+	$command -w -t mangle -N qos_${cg}_ct
+EOF
+done
+cat <<EOF
+	${iptrules:+${iptrules}${N}}
+EOF
+for command in $iptables; do
+	cat <<EOF
+	$command -w -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff
+	$command -w -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0x0f
+	$command -w -t mangle -A qos_${cg} -m mark --mark 0/0x0f -j qos_${cg}_ct
+EOF
+done
+cat <<EOF
 $pktrules
-${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg} -j CONNMARK --save-mark --mask 0xff}
+EOF
+for command in $iptables; do
+	cat <<EOF
+	$command -w -t mangle -A qos_${cg} -j CONNMARK --save-mark --mask 0xff
+EOF
+done
+cat <<EOF
 $up$N${down:+${down}$N}
 EOF
 	unset INSMOD
@@ -447,20 +475,22 @@ stop_firewall() {
 	# remove rules referring to them, then delete them
 
 	# Print rules in the mangle table, like iptables-save
-	iptables -t mangle -S |
-		# Find rules for the qos_* chains
-		grep '^-N qos_\|-j qos_' |
-		# Exclude rules in qos_* chains (inter-qos_* refs)
-		grep -v '^-A qos_' |
-		# Replace -N with -X and hold, with -F and print
-		# Replace -A with -D
-		# Print held lines at the end (note leading newline)
-		sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \
-			-e 's/^-A/-D/' \
-			-e '${p;g}' |
-		# Make into proper iptables calls
-		# Note:  awkward in previous call due to hold space usage
-		sed -n -e 's/^./iptables -t mangle &/p'
+	for command in $iptables; do
+		$command -w -t mangle -S |
+			# Find rules for the qos_* chains
+			grep -E '(^-N qos_|-j qos_)' |
+			# Exclude rules in qos_* chains (inter-qos_* refs)
+			grep -v '^-A qos_' |
+			# Replace -N with -X and hold, with -F and print
+			# Replace -A with -D
+			# Print held lines at the end (note leading newline)
+			sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \
+				-e 's/^-A/-D/' \
+				-e '${p;g}' |
+			# Make into proper iptables calls
+			# Note:  awkward in previous call due to hold space usage
+			sed -n -e "s/^./${command} -w -t mangle &/p"
+	done
 }
 
 C="0"
@@ -475,6 +505,12 @@ for iface in $INTERFACES; do
 	export C="$(($C + 1))"
 done
 
+[ -x /usr/sbin/ip6tables ] && {
+	iptables="ip6tables iptables"
+} || {
+	iptables="iptables"
+}
+
 case "$1" in
 	all)
 		start_interfaces "$C"
diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
index 12f94a6..21df391 100644
--- a/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
+++ b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
@@ -84,7 +84,7 @@ END {
 
 	# filter rule
 	for (i = 1; i <= n; i++) {
-		filter_cmd = "tc filter add dev "device" parent 1: prio %d protocol ip handle %s fw flowid 1:%d0\n";
+		filter_cmd = "tc filter add dev "device" parent 1: prio %d handle %s fw flowid 1:%d0\n";
 		if (direction == "up") {
 			filter_1 = sprintf("0x%x0/0xf0", class[i])
 			filter_2 = sprintf("0x0%x/0x0f", class[i])
-- 
2.7.0
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list