I have shared my internet connection and sometimes my connection is killed by Kazaa and FTPs. I'd like to shape the network so Kazaa upload gets eg 1KB/s upload and FTP in daytime 10KB/s max.
How could I accomplish that?
Using Debian and I have the support for QoS modules in my kernel.
TIA :)
from the Kernel Documentation:
you'll need the user-level utilities from the package iproute2+tc at <ftp://ftp.inr.ac.ru/ip-routing/>.
That package also contains some documentation; for more, check out http://snafu.freedom.org/linux2.2/iproute-notes.html>.
This Quality of Service (QoS) support will enable you to use Differentiated Services (diffserv) and Resource Reservation Protocol (RSVP) on your Linux router if you also say Y to "QoS support", "Packet classifier API" and to some classifiers below. Documentation and software is at <http://icawww1.epfl.ch/linux-diffserv/>.
I have iproute2-ss991023 installed.
I tried this (http://www.hot.ee/tarmospam/fisss/fisss-0.2.0.tar.gz) script but it didn't work so usefully :(
#!/bin/bash
################################################## ##############################
# #
# FISSS - Fair(ly) Intelligent Shaping for Simple Situations #
# #
# Version........: 0.2.0 #
# Created........: 29.05.2003 #
# Last modified..: 17.11.2003 #
# Author.........: Tarmo Kuuse <tarmospam@hot.ee> #
# Copying........: This script is free software; you can redistribute it #
# and/or modify it under the terms of the GNU General Public License #
# http://www.gnu.org/licenses/gpl.txt #
# #
# Description....: #
################################################## ##############################
# Declare these variables as arrays
declare -a I2L_SRC_PORTS_10 I2L_SRC_PORTS_20 I2L_SRC_PORTS_110 \
I2L_SRC_PORTS_120 I2L_SRC_PORTS_130 I2L_SRC_PORTS_140 I2L_SRC_PORTS_50
################################################## ##############################
# User configurable section begins #
################################################## ##############################
# You really should make sure that the values in this section are rigth.
# Otherwise the whole thing might not function.
# External interface device name (connects us to the Internet)
EXT_IF="eth1"
# Internal interface device name (connects us to the LAN)
INT_IF="eth0"
# Downlink throughput, in kilobits per second (tc - kbit)
TP_DOWN="256"
# Uplink throughput, in kilobits per second (tc - kbit)
TP_UP="128"
################################################## ##############################
# Filter configuration #
################################################## ##############################
# Here we decide where incoming packets are queued. All decisions are based on
# the source port.
# If you want to apply some other fancy filters, do it manually below, in the
# section "Filters"
# Incoming traffic, internet -> LAN
# Source ports
I2L_SRC_PORTS_10=(22 23 53)
I2L_SRC_PORTS_20=(21 123 194 443 554 1863 4000 5020 5050 5190 6667 8000 8050)
I2L_SRC_PORTS_110=(80 8080)
I2L_SRC_PORTS_120=(25 110 119 143 220 993 995)
I2L_SRC_PORTS_130=(20)
I2L_SRC_PORTS_140=(1214 2234 2235 2236 2237 2238 2239 2240 4662 4665 5025 \
6257 6346)
I2L_SRC_PORTS_50=()
# Outgoing traffic, LAN -> internet
# Destination ports
L2I_DST_PORTS_10=(22 23 53)
L2I_DST_PORTS_20=(21 25 80 123 194 443 554 1863 4000 5050 5190 6667\
8000 8050 8080)
L2I_DST_PORTS_30=(20 1214 2234 2235 2236 2237 2238 2239 2240 4662 4665 5025 \
6257 6346)
################################################## ##############################
# User configurable section ends #
################################################## ##############################
# Fetch our script name from the shell
SELF_NAME=`basename "$0"`
# A really short usage description
USAGE_MSG="Usage: $SELF_NAME {start|start-int|start-ext|stop|stop-int|stop-ext|restart|status-int|status-ext}"
# tc does not allow zero rates. So i use 1kbit (1 kilobit per second) instead.
# Ahh, in the good old days this was nearly the standard modem speed...
ALMOST_ZERO=1
################################################## ##############################
# Function definitions #
################################################## ##############################
# Something nasty happened, let's log it and quit
# Argument $1 should describe error condition
critical_error () {
local ERR_MSG
ERR_MSG="Ay carramba, $SELF_NAME script failed: $1"
logger -p kern.crit $ERR_MSG
echo -e "\n$ERR_MSG"
exit 1
}
# Something unpleasant happened, let's log it
# Argument $1 should describe warning details
just_a_warning () {
local ERR_MSG
ERR_MSG="Ay carramba, $SELF_NAME script issued a warning: $1"
logger -p kern.warn $ERR_MSG
echo -e "\n$ERR_MSG"
}
# Pinpoint tc executable
if [ -x "/sbin/tc" ]
then
TC="/sbin/tc"
else
if (which tc)
then
TC="`which tc`"
else
critical_error "No tc executable found!"
fi
fi
# Clear all qdisks and ingress stuff from device root. Argument $1 tells
# which interface to clean out.
clear_interface_root () {
if [ $1 ]
then
# If the interface has nothing deletable, we get lots of nasty-looking
# error messages. To maintain user's sanity, we send those to /dev/null
tc qdisc del dev $1 root 2> /dev/null
tc qdisc del dev $1 ingress 2> /dev/null
else
critical_error "Function \"clear_root\": missing argument \$1!"
fi
}
# All QoS functions for the internal LAN interface go here. That means traffic
# coming from the internet and going to LAN. We can effectively shape only
# outgoing traffic, after all.
shape_internet2lan () {
################################################## ##########################
# Some variables #
################################################## ##########################
# Speed limits for classes
R_20_1="$[30*$TP_DOWN/32]kbit"
CR_20_1="$[30*$TP_DOWN/32]kbit"
R_20_10="$[5*$TP_DOWN/32]kbit"
CR_20_10="$[20*$TP_DOWN/32]kbit"
R_20_20="$[10*$TP_DOWN/32]kbit"
CR_20_20="$[30*$TP_DOWN/32]kbit"
R_20_30="$[10*$TP_DOWN/32]kbit"
CR_20_30="$[25*$TP_DOWN/32]kbit"
R_20_40="$[5*$TP_DOWN/32]kbit"
CR_20_40="$[25*$TP_DOWN/32]kbit"
R_20_50="${ALMOST_ZERO}kbit"
CR_20_50="$[20*$TP_DOWN/32]kbit"
R_20_110="$[8*$TP_DOWN/32]kbit"
CR_20_110="$[20*$TP_DOWN/32]kbit"
R_20_120="$[2*$TP_DOWN/32]kbit"
CR_20_120="$[20*$TP_DOWN/32]kbit"
R_20_130="$[5*$TP_DOWN/32]kbit"
CR_20_130="$[25*$TP_DOWN/32]kbit"
R_20_140="${ALMOST_ZERO}kbit"
CR_20_140="$[25*$TP_DOWN/32]kbit"
# Total downlink burst and ceiling burst values, applied to class 20:1
# In kilobytes (tc - kb)
BURST_1=100
CBURST_1=100
# Burst values for 20:30. In kilobytes (tc - kb).
BURST_30=100
CBURST_30=100
# Burst values for 20:110 (mainly HTTP traffic). In kilobytes (tc - kb).
BURST_110=100
CBURST_110=100
################################################## ##########################
# Queueing disciplines and classes #
################################################## ##########################
# Create a PRIO qdisc with 3 bands. This will separate local and internet
# traffic. Band 1 gets local and band 2 gets internet traffic. Band 3 is
# for stuff that slips past my firewall rules.
$TC qdisc add dev $INT_IF root handle 1: prio \
bands 3 priomap 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
# qdisc for me->lan traffic. Usually doesn't need any shaping.
$TC qdisc add dev $INT_IF parent 1:1 pfifo
# HTB qdisc for internet->local traffic. That't the interesting branch.
$TC qdisc add dev $INT_IF parent 1:2 handle 20: htb default 50
# qdisc for unknown traffic. We'll limit it just in case.
$TC qdisc add dev $INT_IF parent 1:3 tbf \
rate 200kbit buffer 2000 limit 3000
# HTB classes
# Root class for the shaping hierarchy. Here we limit throughput a little
# below link speed in order to move the queue from the ISP to this box.
# Otherwise this script would be pretty much useless.
# Needs a big burst because some children need it.
$TC class add dev $INT_IF parent 20: classid 20:1 htb \
rate $R_20_1 ceil $CR_20_1 \
burst ${BURST_1}kb cburst ${BURST_1}kb
# 20:10, priority 0, leaf class
$TC class add dev $INT_IF parent 20:1 classid 20:10 htb \
prio 0 rate $R_20_10 ceil $CR_20_10
# 20:20, priority 1, leaf class
$TC class add dev $INT_IF parent 20:1 classid 20:20 htb \
prio 1 rate $R_20_20 ceil $CR_20_20
# 20:30, priority 2, has 2 children, big burst
$TC class add dev $INT_IF parent 20:1 classid 20:30 htb \
prio 2 rate $R_20_30 ceil $CR_20_30 \
burst ${BURST_30}kb cburst ${BURST_30}kb
# 20:40, priority 3, has 2 children
$TC class add dev $INT_IF parent 20:1 classid 20:40 htb \
prio 3 rate $R_20_40 ceil $CR_20_40
# 20:50, priority 3, leaf class
$TC class add dev $INT_IF parent 20:1 classid 20:50 htb \
prio 3 rate $R_20_50 ceil $CR_20_50
# 20:110, child class for class 20:30, leaf class.
# Needs high burst due to HTTP traffic.
$TC class add dev $INT_IF parent 20:30 classid 20:110 htb \
prio 1 rate $R_20_110 ceil $CR_20_110 \
burst ${BURST_110}kb cburst ${CBURST_110}kb
# 20:120, child class for class 20:30, leaf class
$TC class add dev $INT_IF parent 20:30 classid 20:120 htb \
prio 2 rate $R_20_120 ceil $CR_20_120
# 20:130, child class for class 20:40, leaf class
$TC class add dev $INT_IF parent 20:40 classid 20:130 htb \
prio 1 rate $R_20_130 ceil $CR_20_130
# 20:140, child class for class 20:40, leaf class
$TC class add dev $INT_IF parent 20:40 classid 20:140 htb \
prio 2 rate $R_20_140 ceil $CR_20_140
# qdiscs for HTB leaf classes
#$TC qdisc add dev $INT_IF parent 1:1 pfifo
#$TC qdisc add dev $INT_IF parent 1:3 tbf \
# rate 100kbps latency 100ms burst 15000
$TC qdisc add dev $INT_IF parent 20:10 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:20 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:50 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:110 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:120 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:130 sfq perturb 10
$TC qdisc add dev $INT_IF parent 20:140 sfq perturb 10
################################################## ##########################
# Filters #
################################################## ##########################
# Filters for splitting local and internet traffic
# Traffic from this box to LAN. The mark value "1000" is set by the firewall
$TC filter add dev $INT_IF parent 1:0 protocol ip prio 1 handle 1000 \
fw flowid 1:1
# Traffic from internet to LAN. The mark value "1000" is set by the firewall
$TC filter add dev $INT_IF parent 1:0 protocol ip prio 1 handle 2000 \
fw flowid 1:2
# This is a catch-all filter for packets that did not get marked for some
# reason.
$TC filter add dev $INT_IF parent 1:0 protocol ip prio 20 u32 \
match u8 0x80 0xf0 flowid 1:3
# Filters that classify packets in HTB classes
for (( pc=0; pc < ${#I2L_SRC_PORTS_10 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 10 u32 \
match ip sport ${I2L_SRC_PORTS_10[pc]} 0xffff flowid 20:10
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_20 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 11 u32 \
match ip sport ${I2L_SRC_PORTS_20[pc]} 0xffff flowid 20:20
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_110 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 12 u32 \
match ip sport ${I2L_SRC_PORTS_110[pc]} 0xffff flowid 20:110
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_120 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 13 u32 \
match ip sport ${I2L_SRC_PORTS_120[pc]} 0xffff flowid 20:120
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_130 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 14 u32 \
match ip sport ${I2L_SRC_PORTS_130[pc]} 0xffff flowid 20:130
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_140 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 15 u32 \
match ip sport ${I2L_SRC_PORTS_140[pc]} 0xffff flowid 20:140
done
for (( pc=0; pc < ${#I2L_SRC_PORTS_50 }; pc++ ))
do
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 16 u32 \
match ip sport ${I2L_SRC_PORTS_50[pc]} 0xffff flowid 20:50
done
# All ICMP packets get high priority
$TC filter add dev $INT_IF parent 20:0 protocol ip prio 10 u32 \
match ip protocol 1 0xff flowid 20:10
}
# All QoS functions for the external PPP interface go here. That means traffic
# coming from the LAN and this box going to the Internet.
shape_lan2internet () {
################################################## ##########################
# Some variables #
################################################## ##########################
# Speed limits for classes
R_1_1="$[15*$TP_UP/16]kbit"
CR_1_1="$[15*$TP_UP/16]kbit"
R_1_10="$[9*$TP_UP/16]kbit"
CR_1_10="$[15*$TP_UP/16]kbit"
R_1_20="$[6*$TP_UP/16]kbit"
CR_1_20="$[9*$TP_UP/16]kbit"
R_1_30="${ALMOST_ZERO}kbit"
CR_1_30="$[12*$TP_UP/16]kbit"
################################################## ##########################
# Queueing disciplines and classes #
################################################## ##########################
$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 $R_1_1 ceil $CR_1_1
$TC class add dev $EXT_IF parent 1:1 classid 1:10 htb \
prio 0 rate $R_1_10 ceil $CR_1_10
$TC class add dev $EXT_IF parent 1:1 classid 1:20 htb \
prio 1 rate $R_1_20 ceil $CR_1_20
$TC class add dev $EXT_IF parent 1:1 classid 1:30 htb \
prio 2 rate $R_1_30 ceil $CR_1_30
################################################## ##########################
# Filters #
################################################## ##########################
# TOS minimize delay gets high priority
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 10 u32 \
match ip tos 0x10 0xff flowid 1:10
# All ICMP packets get high priority
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 10 u32 \
match ip protocol 1 0xff flowid 1:10
# ACK packets get high priority
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 10 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:10
# TOS maximize thorugput gets low priority
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 10 u32 \
match ip tos 0x08 0xff flowid 1:30
for (( pc=0; pc < ${#L2I_DST_PORTS_10 }; pc++ ))
do
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 11 u32 \
match ip dport ${L2I_DST_PORTS_10[pc]} 0xffff flowid 1:10
done
for (( pc=0; pc < ${#L2I_DST_PORTS_20 }; pc++ ))
do
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 12 u32 \
match ip dport ${L2I_DST_PORTS_20[pc]} 0xffff flowid 1:20
done
for (( pc=0; pc < ${#L2I_DST_PORTS_30 }; pc++ ))
do
$TC filter add dev $EXT_IF parent 1:0 protocol ip prio 13 u32 \
match ip dport ${L2I_DST_PORTS_30[pc]} 0xffff flowid 1:30
done
}
show_status_int () {
$TC -s class show dev $INT_IF
}
show_status_ext () {
$TC -s class show dev $EXT_IF
}
# Good old init-style.
case "$1" in
start)
echo -n "Setting up QoS for devices $INT_IF and $EXT_IF "
shape_internet2lan
shape_lan2internet
echo "."
;;
start-int)
echo -n "Setting up QoS for device $INT_IF "
shape_internet2lan
echo "."
;;
start-ext)
echo -n "Setting up QoS for device $EXT_IF "
shape_lan2internet
echo "."
;;
stop)
echo -n "Stopping QoS for devices $INT_IF and $EXT_IF "
clear_interface_root $INT_IF
clear_interface_root $EXT_IF
echo "."
;;
stop-int)
echo -n "Stopping QoS for device $INT_IF "
clear_interface_root $INT_IF
echo "."
;;
stop-ext)
echo -n "Stopping QoS for device $EXT_IF "
clear_interface_root $EXT_IF
echo "."
;;
restart|reload)
echo -n "Restarting QoS for devices $INT_IF and $EXT_IF "
clear_interface_root $INT_IF
clear_interface_root $EXT_IF
shape_internet2lan
shape_lan2internet
echo "."
;;
status-int)
show_status_int
;;
status-ext)
show_status_ext
;;
*)
echo "$USAGE_MSG"
exit 1
;;
esac
How do I set the FTP speed for example?