qos-scripts: Add IPv6 support

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@michaelmarley.com>

SVN-Revision: 48452
This commit is contained in:
Felix Fietkau 2016-01-22 11:59:03 +00:00
parent f57419d26e
commit d3f3132057
2 changed files with 64 additions and 28 deletions

View file

@ -339,11 +339,11 @@ tc class add dev $dev parent 1: classid 1:1 hfsc sc rate ${rate}kbit ul rate ${r
if [ -n "$halfduplex" ]; then if [ -n "$halfduplex" ]; then
export dev_up="tc qdisc del dev $device root >&- 2>&- export dev_up="tc qdisc del dev $device root >&- 2>&-
tc qdisc add dev $device root handle 1: hfsc 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 elif [ -n "$download" ]; then
append dev_${dir} "tc qdisc del dev $device ingress >&- 2>&- append dev_${dir} "tc qdisc del dev $device ingress >&- 2>&-
tc qdisc add dev $device ingress 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 fi
add_insmod cls_fw add_insmod cls_fw
add_insmod sch_hfsc add_insmod sch_hfsc
@ -400,17 +400,23 @@ start_cg() {
local pktrules local pktrules
local sizerules local sizerules
enum_classes "$cg" 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 config_get classes "$cg" classes
for class in $classes; do for class in $classes; do
config_get mark "$class" classnr config_get mark "$class" classnr
config_get maxsize "$class" maxsize config_get maxsize "$class" maxsize
[ -z "$maxsize" -o -z "$mark" ] || { [ -z "$maxsize" -o -z "$mark" ] || {
add_insmod xt_length 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 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 for iface in $INTERFACES; do
config_get classgroup "$iface" classgroup config_get classgroup "$iface" classgroup
config_get device "$iface" device config_get device "$iface" device
@ -419,18 +425,40 @@ start_cg() {
config_get download "$iface" download config_get download "$iface" download
config_get halfduplex "$iface" halfduplex config_get halfduplex "$iface" halfduplex
download="${download:-${halfduplex:+$upload}}" download="${download:-${halfduplex:+$upload}}"
append up "iptables -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N" for command in $iptables; do
append up "iptables -t mangle -A FORWARD -o $device -j qos_${cg}" "$N" 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 done
cat <<EOF cat <<EOF
$INSMOD $INSMOD
iptables -t mangle -N qos_${cg} >&- 2>&- EOF
iptables -t mangle -N qos_${cg}_ct >&- 2>&-
${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff} for command in $iptables; do
iptables -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0x0f cat <<EOF
iptables -t mangle -A qos_${cg} -m mark --mark 0/0x0f -j qos_${cg}_ct $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 $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} $up$N${down:+${down}$N}
EOF EOF
unset INSMOD unset INSMOD
@ -450,20 +478,22 @@ stop_firewall() {
# remove rules referring to them, then delete them # remove rules referring to them, then delete them
# Print rules in the mangle table, like iptables-save # Print rules in the mangle table, like iptables-save
iptables -t mangle -S | for command in $iptables; do
# Find rules for the qos_* chains $command -w -t mangle -S |
grep '^-N qos_\|-j qos_' | # Find rules for the qos_* chains
# Exclude rules in qos_* chains (inter-qos_* refs) grep -E '(^-N qos_|-j qos_)' |
grep -v '^-A qos_' | # Exclude rules in qos_* chains (inter-qos_* refs)
# Replace -N with -X and hold, with -F and print grep -v '^-A qos_' |
# Replace -A with -D # Replace -N with -X and hold, with -F and print
# Print held lines at the end (note leading newline) # Replace -A with -D
sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \ # Print held lines at the end (note leading newline)
-e 's/^-A/-D/' \ sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \
-e '${p;g}' | -e 's/^-A/-D/' \
# Make into proper iptables calls -e '${p;g}' |
# Note: awkward in previous call due to hold space usage # Make into proper iptables calls
sed -n -e 's/^./iptables -t mangle &/p' # Note: awkward in previous call due to hold space usage
sed -n -e "s/^./${command} -w -t mangle &/p"
done
} }
C="0" C="0"
@ -478,6 +508,12 @@ for iface in $INTERFACES; do
export C="$(($C + 1))" export C="$(($C + 1))"
done done
[ -x /usr/sbin/ip6tables ] && {
iptables="ip6tables iptables"
} || {
iptables="iptables"
}
case "$1" in case "$1" in
all) all)
start_interfaces "$C" start_interfaces "$C"

View file

@ -84,7 +84,7 @@ END {
# filter rule # filter rule
for (i = 1; i <= n; i++) { 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") { if (direction == "up") {
filter_1 = sprintf("0x%x0/0xf0", class[i]) filter_1 = sprintf("0x%x0/0xf0", class[i])
filter_2 = sprintf("0x0%x/0x0f", class[i]) filter_2 = sprintf("0x0%x/0x0f", class[i])