QOS script to prioritise VOIP

Download Opera


Hi,

Thought I would write a little "How to" in setting up QOS for VOIP.
For QOS to work properly it must be processed just before the modem. This is usually done using a router or modem/router.

There are many different combinations of hardware and software but for this "How to" I am using a router running linux.

The setup is a modem connected to a router connected to a switch with a sipura2000 unit and multiple computers connected to the switch.

If you have a modem connected to one computer then this setup is overkill. But if you have more then one computer on your home network then this setup will improve your VOIP QOS. You could go and by a router with QOS but this setup will give you more control in allocating bandwidth.

The router can be any old computer with at least 16 meg of memory and two network cards. One network card will be used to connect to the modem and the other network card connects to the switch via a lan cable. My setup is an old p180 with 48 meg of ram and no hard drive with two old lan cards. You can pick the whole lot up at a swap meet for about $25.

The software I use to run the router is Coyote linux
http://www.coyotelinux.com/products.php?Product=coyote

It fits onto one floppy and loads and runs in ram. You do not need a hard drive. You can use windows to create the disk. Once it is running you can login via a terminal session, or via a web browser on the lan or via ssh using Putty on a windows machine. There are other linux router distributions such as IpCop, Monowall etc. Any of these can be used.

Just a warning - read all the documentation. First time setup might be confusing but if you follow the instructions then you will be fine. Coyote has a good forum for help.

To make your QOS even more sophisticated you can add layer 7 filtering. You find this kind of filtering in $40,000 routers. It allows you to filter applications bandwidth usage such as bittorrent, Kazaa, emule msn etc.

The web site for layer 7 software is
http://l7-filter.sourceforge.net/ 

Packages for layer 7 filtering have already been compiled for Coyote.
Download the following files and add them to the floppy disk that contains Coyote,
http://fgrant.customer.netspace.net.au/layer7/linux add to the floppy
http://fgrant.customer.netspace.net.au/layer7/iptables.tgz Just add to the floppy
http://fgrant.customer.netspace.net.au/layer7/l7filter.tgz Just add to floppy

Once you have Coyote running it is time to turn on QOS.

First of all you need to give the Sipura unit a fixed ip address. Connect to your router by keying in its address in your browser. For example my routers address is 192.168.1.1. Therefore I load 192.168.1.1:8180 into my browser. Click on DHCP configuration. Down the bottom click on Current DHCP Leases and Reservations. You should see your Sipura with an ip address. Add it to reservations. Remember its IP address.

Back to the main menu click on QOS configurations. Click Wonder-shaper init scripts.
Don't worry about filling in values, we are going to replace the wonder-shaper script with a new script.

On the main menu click on Configuration Files
Click on - Edit Any File

Enter /etc/rc.d/rc.qos.wonder

Now we are going to replace what is in that file with this script but you need to revise the script to suit your setup.

This script can be used on any linux system that has iptables and netfilter
You can run the script manually by opening a terminal session or starting up Putty http://www.putty.nl/
in windows and logging into your linux box.

Then cd /etc/rc.d
and run the command sh rc.qos
This script will start up your QOS script in rc.qos.wonder.

Or you can just sh rc.qos.wonder.

If you are using some other linux router then put the script were it will run each time your router connects to the internet.

You can also get a listing of whats happening by running the command
sh rc.qos.wonder status

Read the script carefully and you will work out what it is doing.

Here is the script

#!/bin/sh

PATH=$PATH:/usr/sbin

# This setup for a 1500/256 adsl link.
# A 512/125 link would be DOWNLINK = 400 UPLINK = 90
DOWNLINK=1200
UPLINK=200

# This is the interface that the data goes in and out through
# If you a on cable then it might be eth1
DEV=ppp0

#The sipura2000 has been fixed with an ip address of 192.168.1.66
# Change this to your Sipura's address
VOIP=192.168.1.66

# Change these values to suit your connection.
# The 4 values must add up to the UPLINK value
# The values are the minimum that link will receive
# The sipura is using a high quality 64kbit codec
# It is better to over supply bandwidth to VOIP
VOIPRATE=100kbit
SECOND=40kbit
THIRDPRIO=20kbit
P2P=40kbit

if [ "$1" = "status" ]
then
tc -s qdisc ls dev ppp0
tc -s class ls dev ppp0
exit
fi

# clean existing down- and uplink qdiscs, hide errors
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null

# Flush the PREROUTING
iptables -t mangle -F PREROUTING

if [ "$1" = "stop" ]
then
exit
fi

###### uplink

# install root HTB, point default traffic to 1:12.
# All traffic not classified below will default to 1:12 which is THIRDPRIO
tc qdisc add dev $DEV root handle 1: htb default 12 r2q 1

# shape everything at $UPLINK speed - this prevents huge queues in your
# DSL modem which destroy latency:
tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit ceil ${UPLINK}kbit

# high priority class 1:10: VOIP rate
tc class add dev $DEV parent 1:1 classid 1:10 htb rate $VOIPRATE ceil ${UPLINK}kbit prio 0

# Ping Ack ssh http email etc class 1:11 - gets slightly less traffic,
# and a lower priority:
tc class add dev $DEV parent 1:1 classid 1:11 htb rate $SECOND ceil ${UPLINK}kbit prio 1

# This is for any protocol not mentioned. Lower priority again
tc class add dev $DEV parent 1:1 classid 1:12 htb rate $THIRDPRIO ceil ${UPLINK}kbit prio 2

# Lowest priority. Used for p2p, ftp
tc class add dev $DEV parent 1:1 classid 1:13 htb rate $P2P ceil ${UPLINK}kbit prio 3

# All the zones except zone 1:10 (VOIP) get Stochastic Fairness:
# VOIP gets first in first out queuing
tc qdisc add dev $DEV parent 1:10 handle 10: pfifo
tc qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10
tc qdisc add dev $DEV parent 1:12 handle 12: sfq perturb 10
tc qdisc add dev $DEV parent 1:13 handle 13: sfq perturb 10

# Match the traffic from VOIP and give it highest priority
# This requires iptables matching compiled into the kernel
iptables -A PREROUTING -i eth0 -s $VOIP -t mangle -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -s $VOIP -t mangle -j RETURN


# This machine runs a ftp server and emule client
# It will be given a low priority
# If you do not have any machine that you want to give special attention too
# then leave these two lines out or modifiy them
iptables -A PREROUTING -i eth0 -s 192.168.1.6 -t mangle -j MARK --set-mark 2
iptables -A PREROUTING -i eth0 -s 192.168.1.6 -t mangle -j RETURN

# This is using layer7 matching to mark kazaa and bittorrent traffic
# It will be given a low priority
# There is a list of protocol matching at
http://l7-filter.sourceforge.net/protocols
iptables -A PREROUTING -i eth0 -m layer7 --l7proto fasttrack -t mangle -j MARK --set-mark 2
iptables -A PREROUTING -i eth0 -m layer7 --l7proto fasttrack -t mangle -j RETURN
iptables -A PREROUTING -i eth0 -m layer7 --l7proto bittorrent -t mangle -j MARK --set-mark 2
iptables -A PREROUTING -i eth0 -m layer7 --l7proto bittorrent -t mangle -j RETURN

tc filter add dev $DEV parent 1:0 protocol ip prio 0 handle 1 fw classid 1:10
tc filter add dev $DEV parent 1:0 protocol ip prio 3 handle 2 fw classid 1:13

# TOS Minimum Delay (ssh, NOT scp) in 1:11:
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip tos 0x10 0xff flowid 1:11

# ICMP (ip protocol 1) in the interactive class 1:11 so we
# can do measurements & impress our friends:
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip protocol 1 0xff flowid 1:11

# To speed up downloads while an upload is going on, put ACK packets in
# the interactive class:
tc filter add dev $DEV parent 1:0 protocol ip prio 1 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:11

# Priorized ports 22 25 53 80 110 443
# Put them in the interactive class:
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 22 0xffff flowid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 25 0xffff flowid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 53 0xffff flowid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 80 0xffff flowid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 110 0xffff flowid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \
match ip dport 443 0xffff flowid 1:11


########## downlink #############
# slow downloads down to somewhat less than the real speed to prevent
# queuing at our ISP. Tune to see how high you can set it.
# ISPs tend to have *huge* queues to make sure big downloads are fast
#
# attach ingress policer:

tc qdisc add dev $DEV handle ffff: ingress

# filter *TCP*, drop TCP that are
# coming in too fast:
# Allow UDP - VOIP

tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip protocol 6 0xff \
police rate ${DOWNLINK}kbit burst 10k drop flowid :1

##################### END ###################################