From 3943c9626bd2f4b0829c666406340852cfca66e8 Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Mon, 30 Jan 2017 14:50:26 -0800 Subject: [PATCH] add tc egress shaping --- common.sh | 1 + shaper.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100755 shaper.sh diff --git a/common.sh b/common.sh index f4da792..1e40677 100644 --- a/common.sh +++ b/common.sh @@ -5,6 +5,7 @@ set -e IPTABLES=$(which iptables) IP6TABLES=$(which ip6tables) IPSET=$(which ipset) +TC=$(which tc) err(){ echo "$@" 1>&2 diff --git a/shaper.sh b/shaper.sh new file mode 100755 index 0000000..f335718 --- /dev/null +++ b/shaper.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# settings +UPLINK=11232 #kbit +BURST=15 #k +SHAPE_CHAIN='SHAPER-OUT' +# + +set -e + +. ./common.sh + +if [ $# -lt 1 ] +then + echo "Usage: $(basename "$0") external_interface" 1>&2 + exit 64 +fi + +EXT_IF="$1" +if ! ip link show "${EXT_IF}" >/dev/null 2>&1 +then + echo "'${EXT_IF}' does not seem to be a valid interface" + exit 1 +fi + +function shape_if(){ + local ext_if="$1" uplink="$2" burst="$3" + + $TC qdisc del dev ${ext_if} root >/dev/null 2>&1 || true + + $TC qdisc add dev ${ext_if} root handle 1: htb default 30 + $TC class add dev ${ext_if} parent 1: classid 1:1 htb rate ${uplink}kbit burst ${burst}k + + $TC class add dev ${ext_if} parent 1:1 classid 1:10 htb rate ${uplink}kbit burst ${burst}k prio 1 + $TC class add dev ${ext_if} parent 1:1 classid 1:20 htb rate ${uplink}kbit burst ${burst}k prio 2 + $TC class add dev ${ext_if} parent 1:1 classid 1:30 htb rate $(expr 9 \* ${uplink} / 10)kbit burst ${burst}k prio 3 + $TC class add dev ${ext_if} parent 1:1 classid 1:40 htb rate $(expr 5 \* ${uplink} / 10)kbit burst ${burst}k prio 4 + $TC class add dev ${ext_if} parent 1:1 classid 1:50 htb rate $(expr 5 \* ${uplink} / 10)kbit burst $(expr 2 \* ${burst} / 3)k prio 5 + + for x in $(seq 5) + do + # $TC qdisc add dev ${ext_if} parent 1:${x}0 handle ${x}0: sfq perturb 10 + $TC qdisc add dev ${ext_if} parent 1:${x}0 handle ${x}0: fq_codel + $TC filter add dev ${ext_if} parent 1: prio 0 protocol ip handle ${x} fw flowid 1:${x}0 + done +} + +function shape(){ + local prio="$1" + shift + if ! $IPTABLES -t mangle -C "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio} >/dev/null 2>&1 + then + $IPTABLES -t mangle -A "${SHAPE_CHAIN}" "$@" -j MARK --set-mark ${prio} + fi +} + +shape_if "${EXT_IF}" "${UPLINK}" "${BURST}" + +if ! $IPTABLES -t mangle -L "${SHAPE_CHAIN}" >/dev/null 2>&1 +then + echo "initializing chain '${SHAPE_CHAIN}'" + $IPTABLES -t mangle -N "${SHAPE_CHAIN}" +fi + +shape 1 -p icmp +shape 1 -p udp +shape 1 -p tcp -m length --length :64 +shape 1 -p tcp --syn -m length --length 40:68 +shape 1 -p tcp --tcp-flags ALL ACK -m length --length 40:100 +shape 1 -p tcp --tcp-flags ALL RST +shape 1 -p tcp --tcp-flags ALL ACK,RST +shape 1 -p tcp --tcp-flags ALL ACK,FIN + +shape 2 -p tcp --dport 22 + +shape 4 -p tcp --dport 20 +shape 4 -p tcp --dport 115 + +shape 5 -p tcp --dport 8881:8899 +shape 5 -p tcp --sport 8881:8899 + +if ! $IPTABLES -t mangle -C POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}" >/dev/null 2>&1 +then + $IPTABLES -t mangle -C POSTROUTING -o "${EXT_IF}" -j "${SHAPE_CHAIN}" +fi + -- 2.43.2