I finally got around to fixing the QoS problem with my Callvantage VoIP setup. After determining about 3 months ago that my Callvantage box was dropping packets and causing general outbound havok on my system, I decided to move it inside my network behind my trusty linux firewall/router/mailserver/gameserver box. The unfortunate side effect was that I lost the Quality of Service capabilities. This caused a serious delay in voice transmission and sometimes even stuttering while I was talking on the phone. I usually just accepted it until my friend got his new Actiontec router and it handled VoIP QoS automatically. Now if Actiontec can do it, I know my outdated Redhat 7.3 install should be able to.
I started looking around and ran into the ADSL Bandwidth Management HOW-TO. After playing with this one for a while, I realized that I didn’t have the proper imq device listed in the prerequisites. However, this gave me some great background on how it works. There was a tiny nugget of guidance in the related links section pointing to dsl_qos_queue which said no kernel patching. I downloaded the package (precompiled) and it already had the libipq compiled as part of it. Wow!
There is a serious lack of documentation with this amazing product but through some digging in the source code, I was able to find switches to point it to eth1 for my outbound interface instead of the default eth0. (to find the help, it’s dsl_qos_queue -h, not –help or -? or /? or anything I guessed on the first try) On my first attempt, it worked perfectly for giving me low-latency VoIP for my Callvantage but it really choked my upstream speed for everything else. Back to the switches I found that there was a cap rate switch that would allow me to specify my max outbound rate in kB/s. DSL reports was telling me that my uprate was about 690kbps, 690000/8 gave me 86250 bytes per second. I changed my switches around a little bit and came up with a start line of “dsl_qos_queue -i eth1 -d -r 96000″. I updated the ipt_rules script to call this after added the marking rules and added one more for my Callvantage box. I then copied the whole shebang to my /etc/shorewall/tcstart file (traffic shaping for shorewall) and modified the shorewall.conf file and set TC_ENABLED=yes which makes shorewall automatically call the tcstart file when I start up my firewall. I also set CLEAR_TC=Yes to clear out the rules on startup, even though it’s already part of the script. Here is the modified ipt_rules file copied to tcstart for your reference.
#!/bin/bash # add MYSHAPER-OUT chain to the mangle table in iptables - this sets up the table we'll use # to filter and mark packets. killall dsl_qos_queue DEV=eth1 # Reset everything to a known state (cleared) iptables -t mangle -D POSTROUTING -o $DEV -j MYSHAPER-OUT 2> /dev/null > /dev/null iptables -t mangle -F MYSHAPER-OUT 2> /dev/null > /dev/null iptables -t mangle -X MYSHAPER-OUT 2> /dev/null > /dev/null #if [ "$1" != "install" ] #then # exit #fi iptables -t mangle -N MYSHAPER-OUT iptables -t mangle -I POSTROUTING -o $DEV -j MYSHAPER-OUT # add fwmark entries to classify different types of traffic - Set fwmark from 20-26 according to # desired class. 20 is highest prio. iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 0:1024 -j MARK --set-mark 23 # Default for low port traffic iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 0:1024 -j MARK --set-mark 23 # "" iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 20 -j MARK --set-mark 26 # ftp-data port, low prio iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5190 -j MARK --set-mark 23 # aol instant messenger iptables -t mangle -A MYSHAPER-OUT -p icmp -j MARK --set-mark 20 # ICMP (ping) - high prio, impress friends iptables -t mangle -A MYSHAPER-OUT -p udp --dport 123 -j MARK --set-mark 20 # NTP should be low-lag iptables -t mangle -A MYSHAPER-OUT -p udp --dport 53 -j MARK --set-mark 21 # DNS name resolution (small packets) iptables -t mangle -A MYSHAPER-OUT -p tcp --dport ssh -j MARK --set-mark 22 # secure shell iptables -t mangle -A MYSHAPER-OUT -p tcp --sport ssh -j MARK --set-mark 22 # secure shell iptables -t mangle -A MYSHAPER-OUT -p tcp --dport telnet -j MARK --set-mark 22 # telnet (ew...) iptables -t mangle -A MYSHAPER-OUT -p tcp --sport telnet -j MARK --set-mark 22 # telnet (ew...) iptables -t mangle -A MYSHAPER-OUT -p ipv6-crypt -j MARK --set-mark 24 # IPSec - we dont know what the payload is though... iptables -t mangle -A MYSHAPER-OUT -p tcp --sport http -j MARK --set-mark 25 # Local web server iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length :64 -j MARK --set-mark 21 # small packets (probably just ACKs) iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 3389 -j MARK --set-mark 23 # windows remote computer connection iptables -t mangle -A MYSHAPER-OUT -s 192.168.0.211 -j MARK --set-mark 20 # Callvantage box traffic should be high-prio iptables -t mangle -A MYSHAPER-OUT -m mark --mark 0 -j MARK --set-mark 26 # redundant- mark any unmarked packets as 26 (low pri /root/dsl_qos_queue/dsl_qos_queue -i eth1 -d -r 85250
This works great and I hope it gives you AT&T Callvantage, Vonage and other VoIP users a good starting point for traffic control through Linux.