Add support for kbit/s rates
This commit is contained in:
parent
905d62e4a6
commit
c135e2131d
12
README.md
12
README.md
|
|
@ -8,19 +8,19 @@ Run tc-gen.sh without parameters to see more details.
|
||||||
|
|
||||||
## Examples of common use
|
## Examples of common use
|
||||||
Shape egress to 25 mbit/s
|
Shape egress to 25 mbit/s
|
||||||
|
|
||||||
tc-gen.sh -i eth0 -u 25
|
tc-gen.sh -i eth0 -u 25
|
||||||
Shape egress to 5 mbit/s and ingress to 10 mbit/s using IFB-interface
|
Shape egress to 5 mbit/s and ingress to 10 mbit/s using IFB-interface
|
||||||
|
|
||||||
tc-gen.sh -i eth0 -u 5 -d 10 -f ifb0
|
tc-gen.sh -i eth0 -u 5 -d 10 -f ifb0
|
||||||
Shape egress to 2 mbit/s and police ingress to 20 mbit/s
|
Shape egress to 1500 kbit/s and police ingress to 20 mbit/s
|
||||||
|
|
||||||
tc-gen.sh -i eth0 -u 2 -d 20
|
tc-gen.sh -i eth0 -u 1500k -d 20M
|
||||||
Display current configuration
|
Display current configuration
|
||||||
|
|
||||||
tc-gen.sh -i eth0
|
tc-gen.sh -i eth0
|
||||||
Remove configuration
|
Remove configuration
|
||||||
|
|
||||||
tc-gen.sh -i eth0 -x
|
tc-gen.sh -i eth0 -x
|
||||||
|
|
||||||
## /etc/network/interfaces examples
|
## /etc/network/interfaces examples
|
||||||
|
|
|
||||||
104
src/tc-gen.sh
104
src/tc-gen.sh
|
|
@ -29,8 +29,11 @@ tc-gen.sh -i IF_NAME [OPTIONS]
|
||||||
configuration on the interface is displayed.
|
configuration on the interface is displayed.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-u UP_RATE_MBITS
|
Valid units for rates are k (kbit/s) and M (Mbit/s). If no unit are given
|
||||||
-d DOWN_RATE_MBITS
|
with the rate Mbit/s is used.
|
||||||
|
|
||||||
|
-u UP_RATE
|
||||||
|
-d DOWN_RATE
|
||||||
-f IFB_IF_NAME
|
-f IFB_IF_NAME
|
||||||
If ingress shaping should be used instead of policing define a valid
|
If ingress shaping should be used instead of policing define a valid
|
||||||
ifb interface. Normally ifb0 and ifb1 are available if nothing is
|
ifb interface. Normally ifb0 and ifb1 are available if nothing is
|
||||||
|
|
@ -44,18 +47,18 @@ OPTIONS
|
||||||
class has a priority of 4. If this is not set all the bandwith is
|
class has a priority of 4. If this is not set all the bandwith is
|
||||||
given to the default class which is sufficient for most use cases.
|
given to the default class which is sufficient for most use cases.
|
||||||
These classes are only used for egress shaping.
|
These classes are only used for egress shaping.
|
||||||
If ceil is not set it will default to UP_RATE_MBITS. If prio is not
|
If ceil is not set it will default to UP_RATE. If prio is not
|
||||||
set, it will default to the same priority as the default class.
|
set, it will default to the same priority as the default class.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
-c "107:50::,109:30:70:2"
|
-c "107:50::,109:1400k:7M:2"
|
||||||
|
|
||||||
The example above creates a leaf class which get all egress traffic
|
The example above creates a leaf class which get all egress traffic
|
||||||
with fw mark 107, shaped to a rate of 50 mbit/s with no ceiling and
|
with fw mark 107, shaped to a rate of 50 mbit/s with no ceiling and
|
||||||
priority, which means that it may use all the available bandwith if
|
priority, which means that it may use all the available bandwith if
|
||||||
available in the root class and has the same priority as the default
|
available in the root class and has the same priority as the default
|
||||||
class. The next leaf class has a fw mark of 109, a rate of 30 mbit/s,
|
class. The next leaf class has a fw mark of 109, a rate of 1400 kbit/s,
|
||||||
a ceil of 70 mbit/s and a priority of 2.
|
a ceil of 7 mbit/s and a priority of 2.
|
||||||
-x
|
-x
|
||||||
Clear all traffic control config on interface.
|
Clear all traffic control config on interface.
|
||||||
-V
|
-V
|
||||||
|
|
@ -68,8 +71,8 @@ EXAMPLES OF COMMON USE
|
||||||
Shape egress to 5 mbit/s and ingress to 10 mbit/s using IFB-interface
|
Shape egress to 5 mbit/s and ingress to 10 mbit/s using IFB-interface
|
||||||
tc-gen.sh -i eth0 -u 5 -d 10 -f ifb0
|
tc-gen.sh -i eth0 -u 5 -d 10 -f ifb0
|
||||||
|
|
||||||
Shape egress to 2 mbit/s and police ingress to 20 mbit/s
|
Shape egress to 1500 kbit/s and police ingress to 20 mbit/s
|
||||||
tc-gen.sh -i eth0 -u 2 -d 20
|
tc-gen.sh -i eth0 -u 1500k -d 20M
|
||||||
|
|
||||||
Display current configuration
|
Display current configuration
|
||||||
tc-gen.sh -i eth0
|
tc-gen.sh -i eth0
|
||||||
|
|
@ -82,16 +85,16 @@ EXAMPLES OF COMMON USE
|
||||||
policing with good results.
|
policing with good results.
|
||||||
|
|
||||||
EGRESS TRAFFIC SHAPING
|
EGRESS TRAFFIC SHAPING
|
||||||
UP_RATE_MBITS uses HTB and fq_codel to efficiently shape upload
|
UP_RATE uses HTB and fq_codel to efficiently shape upload
|
||||||
traffic.
|
traffic.
|
||||||
|
|
||||||
INGRESS TRAFFIC SHAPING
|
INGRESS TRAFFIC SHAPING
|
||||||
If DOWN_RATE_MBITS and IFB_IF_NAME is set, ingress traffic shaping using
|
If DOWN_RATE and IFB_IF_NAME is set, ingress traffic shaping using
|
||||||
an IFB-interface, HTB and fq_codel, is used for incoming traffic.
|
an IFB-interface, HTB and fq_codel, is used for incoming traffic.
|
||||||
|
|
||||||
INGRESS TRAFFIC POLICING
|
INGRESS TRAFFIC POLICING
|
||||||
BURST_SIZE is only used for ingress policing.
|
BURST_SIZE is only used for ingress policing.
|
||||||
Ingress policing is used if IFB_IF_NAME is not defined and DOWN_RATE_MBITS
|
Ingress policing is used if IFB_IF_NAME is not defined and DOWN_RATE
|
||||||
is set. A good starting point for the burst size is
|
is set. A good starting point for the burst size is
|
||||||
|
|
||||||
phy_line_rate_in_bps * burst_time_seconds / 8 = burst_size_in_bytes
|
phy_line_rate_in_bps * burst_time_seconds / 8 = burst_size_in_bytes
|
||||||
|
|
@ -126,11 +129,11 @@ print_version () {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_htb_quantum () {
|
get_htb_quantum () {
|
||||||
# Takes input rate in mbit/s as parameter
|
# Takes input rate in kbit/s as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
local QUANTUM=8000
|
local QUANTUM=8000
|
||||||
|
|
||||||
if [[ ${RATE} -lt 40 ]]; then
|
if [[ ${RATE} -lt 40000 ]]; then
|
||||||
QUANTUM=1514
|
QUANTUM=1514
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -138,10 +141,10 @@ get_htb_quantum () {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_target () {
|
get_target () {
|
||||||
# Takes input rate in mbit/s and mtu as parameter
|
# Takes input rate in kbit/s and mtu as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
local MTU=$2
|
local MTU=$2
|
||||||
local KBYTES=$(( ${RATE} * 1000 / 8 ))
|
local KBYTES=$(( ${RATE} / 8 ))
|
||||||
local MS=$(( ${MTU} / ${KBYTES} ))
|
local MS=$(( ${MTU} / ${KBYTES} ))
|
||||||
local TARGET=5
|
local TARGET=5
|
||||||
|
|
||||||
|
|
@ -153,19 +156,19 @@ get_target () {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_fq_codel_quantum () {
|
get_fq_codel_quantum () {
|
||||||
# Takes input rate in mbit/s as parameter
|
# Takes input rate in kbit/s as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
|
|
||||||
if [[ ${RATE} -lt 100 ]]; then
|
if [[ ${RATE} -lt 100000 ]]; then
|
||||||
echo "quantum 300"
|
echo "quantum 300"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
get_ecn () {
|
get_ecn () {
|
||||||
# Takes input rate in mbit/s as parameter
|
# Takes input rate in kbit/s as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
|
|
||||||
if [[ ${RATE} -ge 4 ]]; then
|
if [[ ${RATE} -ge 4000 ]]; then
|
||||||
echo "ecn"
|
echo "ecn"
|
||||||
else
|
else
|
||||||
echo "noecn"
|
echo "noecn"
|
||||||
|
|
@ -178,10 +181,10 @@ get_mtu () {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_tx_offloads () {
|
get_tx_offloads () {
|
||||||
# Takes rate in mbit/s as parameter
|
# Takes rate in kbit/s as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
|
|
||||||
if [[ ${RATE} -lt 40 ]]; then
|
if [[ ${RATE} -lt 40000 ]]; then
|
||||||
echo "tso off gso off"
|
echo "tso off gso off"
|
||||||
else
|
else
|
||||||
echo "tso on gso on"
|
echo "tso on gso on"
|
||||||
|
|
@ -189,15 +192,15 @@ get_tx_offloads () {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_limit () {
|
get_limit () {
|
||||||
# Takes rate in mbit/s as parameter
|
# Takes rate in kbit/s as parameter
|
||||||
local RATE=$1
|
local RATE=$1
|
||||||
local LIMIT=10000
|
local LIMIT=10000
|
||||||
|
|
||||||
if [[ ${RATE} -le 10 ]]; then
|
if [[ ${RATE} -le 10000 ]]; then
|
||||||
LIMIT=600
|
LIMIT=600
|
||||||
elif [[ ${RATE} -le 100 ]]; then
|
elif [[ ${RATE} -le 100000 ]]; then
|
||||||
LIMIT=800
|
LIMIT=800
|
||||||
elif [[ ${RATE} -le 1000 ]]; then
|
elif [[ ${RATE} -le 1000000 ]]; then
|
||||||
LIMIT=1200
|
LIMIT=1200
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -240,7 +243,7 @@ apply_egress_shaping () {
|
||||||
|
|
||||||
# Set the overall shaped rate of the interface
|
# Set the overall shaped rate of the interface
|
||||||
${TC} class add dev ${IF_NAME} parent 1: classid 1:1 htb \
|
${TC} class add dev ${IF_NAME} parent 1: classid 1:1 htb \
|
||||||
rate ${UP_RATE}mbit \
|
rate ${UP_RATE}kbit \
|
||||||
quantum $(get_htb_quantum ${UP_RATE})
|
quantum $(get_htb_quantum ${UP_RATE})
|
||||||
|
|
||||||
local DEFAULT_RATE=${UP_RATE}
|
local DEFAULT_RATE=${UP_RATE}
|
||||||
|
|
@ -252,8 +255,8 @@ apply_egress_shaping () {
|
||||||
for CLASS in ${CLASSES[@]}; do
|
for CLASS in ${CLASSES[@]}; do
|
||||||
local CONFIG=( $(echo "${CLASS}" | tr ':' ' ') )
|
local CONFIG=( $(echo "${CLASS}" | tr ':' ' ') )
|
||||||
local FWMARK=${CONFIG[0]}
|
local FWMARK=${CONFIG[0]}
|
||||||
local CLASS_RATE=${CONFIG[1]}
|
local CLASS_RATE=$(convert_rate ${CONFIG[1]})
|
||||||
local CEIL_RATE=${CONFIG[2]}
|
local CEIL_RATE=$(convert_rate ${CONFIG[2]})
|
||||||
local PRIO=${CONFIG[3]}
|
local PRIO=${CONFIG[3]}
|
||||||
local CLASS_ID=${FWMARK}
|
local CLASS_ID=${FWMARK}
|
||||||
|
|
||||||
|
|
@ -278,7 +281,7 @@ apply_egress_shaping () {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${TC} class add dev ${IF_NAME} parent 1:1 classid 1:${CLASS_ID} htb \
|
${TC} class add dev ${IF_NAME} parent 1:1 classid 1:${CLASS_ID} htb \
|
||||||
rate ${CLASS_RATE}mbit ceil ${CEIL_RATE}mbit \
|
rate ${CLASS_RATE}kbit ceil ${CEIL_RATE}kbit \
|
||||||
prio ${PRIO} quantum $(get_htb_quantum ${CLASS_RATE})
|
prio ${PRIO} quantum $(get_htb_quantum ${CLASS_RATE})
|
||||||
|
|
||||||
# Should the class rate or ceil be used for the calculations here??
|
# Should the class rate or ceil be used for the calculations here??
|
||||||
|
|
@ -297,8 +300,9 @@ apply_egress_shaping () {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create class for the default priority
|
# Create class for the default priority
|
||||||
${TC} class add dev ${IF_NAME} parent 1:1 classid 1:99 htb rate ${DEFAULT_RATE}mbit \
|
${TC} class add dev ${IF_NAME} parent 1:1 classid 1:99 htb \
|
||||||
ceil ${UP_RATE}mbit prio ${DEFAULT_PRIO} \
|
rate ${DEFAULT_RATE}kbit \
|
||||||
|
ceil ${UP_RATE}kbit prio ${DEFAULT_PRIO} \
|
||||||
quantum $(get_htb_quantum ${UP_RATE})
|
quantum $(get_htb_quantum ${UP_RATE})
|
||||||
|
|
||||||
# Set qdisc to fq_codel
|
# Set qdisc to fq_codel
|
||||||
|
|
@ -321,11 +325,13 @@ apply_ingress_shaping () {
|
||||||
${TC} qdisc add dev ${IFB_IF_NAME} root handle 1: htb default 99
|
${TC} qdisc add dev ${IFB_IF_NAME} root handle 1: htb default 99
|
||||||
|
|
||||||
# Set the overall shaped rate of the interface
|
# Set the overall shaped rate of the interface
|
||||||
${TC} class add dev ${IFB_IF_NAME} parent 1: classid 1:1 htb rate ${DOWN_RATE}mbit
|
${TC} class add dev ${IFB_IF_NAME} parent 1: classid 1:1 htb \
|
||||||
|
rate ${DOWN_RATE}kbit
|
||||||
|
|
||||||
# Create class for the default priority
|
# Create class for the default priority
|
||||||
${TC} class add dev ${IFB_IF_NAME} parent 1:1 classid 1:99 htb rate ${DOWN_RATE}mbit \
|
${TC} class add dev ${IFB_IF_NAME} parent 1:1 classid 1:99 htb \
|
||||||
ceil ${DOWN_RATE}mbit prio 0 \
|
rate ${DOWN_RATE}kbit \
|
||||||
|
ceil ${DOWN_RATE}kbit prio 0 \
|
||||||
quantum $(get_htb_quantum ${DOWN_RATE})
|
quantum $(get_htb_quantum ${DOWN_RATE})
|
||||||
|
|
||||||
# Set qdisc to fq_codel. Enabling ECN is recommended for ingress
|
# Set qdisc to fq_codel. Enabling ECN is recommended for ingress
|
||||||
|
|
@ -362,23 +368,45 @@ apply_ingress_policing () {
|
||||||
# filters earlier in the chain.
|
# filters earlier in the chain.
|
||||||
${TC} filter add dev ${IF_NAME} parent ffff: protocol all prio 99 u32 \
|
${TC} filter add dev ${IF_NAME} parent ffff: protocol all prio 99 u32 \
|
||||||
match u32 0 0 \
|
match u32 0 0 \
|
||||||
police rate ${DOWN_RATE}mbit \
|
police rate ${DOWN_RATE}kbit \
|
||||||
burst ${BURST_SIZE} \
|
burst ${BURST_SIZE} \
|
||||||
mtu ${MTU} drop flowid :1
|
mtu ${MTU} drop flowid :1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convert_rate () {
|
||||||
|
# Takes command line input rate as argument.
|
||||||
|
# Converts rates to kbit/s.
|
||||||
|
local IN_RATE=$1
|
||||||
|
local RATE=0
|
||||||
|
local DEFAULT_REGEX="^([0-9]+)$"
|
||||||
|
local KBIT_REGEX="^([0-9]+)k$"
|
||||||
|
local MBIT_REGEX="^([0-9]+)M$"
|
||||||
|
|
||||||
|
if [[ ${IN_RATE} =~ ${MBIT_REGEX} ]]; then
|
||||||
|
RATE=$(( ${BASH_REMATCH[1]} * 1000 ))
|
||||||
|
elif [[ ${IN_RATE} =~ ${KBIT_REGEX} ]]; then
|
||||||
|
RATE=${BASH_REMATCH[1]}
|
||||||
|
elif [[ ${IN_RATE} =~ ${DEFAULT_REGEX} ]]; then
|
||||||
|
RATE=$(( ${BASH_REMATCH[1]} * 1000 ))
|
||||||
|
else
|
||||||
|
echo "${IN_RATE} is not a valid rate"
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ${RATE}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# All rates should be given in mbit/s
|
|
||||||
while getopts ":i:u:d:b:f:q:c:xV" OPT; do
|
while getopts ":i:u:d:b:f:q:c:xV" OPT; do
|
||||||
case ${OPT} in
|
case ${OPT} in
|
||||||
i)
|
i)
|
||||||
IF_NAME="${OPTARG}"
|
IF_NAME="${OPTARG}"
|
||||||
;;
|
;;
|
||||||
u)
|
u)
|
||||||
UP_RATE="${OPTARG}"
|
UP_RATE=$(convert_rate ${OPTARG})
|
||||||
;;
|
;;
|
||||||
d)
|
d)
|
||||||
DOWN_RATE="${OPTARG}"
|
DOWN_RATE=$(convert_rate ${OPTARG})
|
||||||
;;
|
;;
|
||||||
b)
|
b)
|
||||||
BURST_SIZE="${OPTARG}"
|
BURST_SIZE="${OPTARG}"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue