HFSC and VoIP

2007-02-24 UPDATE:
Gurney Halleck has submitted an improved version of the script: Download.

2011-11-22 UPDATE:
I have set up a HFSC repository on github. Feel free to pull, and if you have any improvements, send pull requests.


Since I started to use the internet telephony, the Quality of Service (QoS) started to be important. When my girlfriend opened a web page, the sound was going choppy. So what I want to is:

  • Have a responsive remote terminal sessions over SSH
  • Stable VoIP telephony
  • Fast web browsing, but not hurting SSH nor VoIP
  • Low-priority traffic for p2p applications, that uses all the bandwidth that isn’t being used for other services

That’s pretty much to want from a 256/128 ADSL line. However, doesn’t seem impossible.

Let’s try to write down classes of network traffic that I want to distinguish.

  • Interactive: SSH sessions, DNS and small ACK packets for establishing TCP connections. They consume small amount of bandwidth, but they need to be fast.
  • VoIP: Talking over the Internet can consume a lot of bandwidth, but it needs priority over browsing and the rest.
  • Web browsing:Web generates short bursts of traffic. They need priority over p2p connections, but should wait for VoIP traffic.
  • General traffic: All traffic that isn’t categorized otherwise. It has lower priority than browsing.
  • P2P: It has the lowest priority of all, but can borrow bandwidth from all other classes, when they’re idle.

HFSC stands for Hierarchical Fair Service Queue. The curve means that you don’t define static bounds for bandwidth allocation for a class. Instead, you specify the early bandwidth allocation, then time and then late allocation.

In HTB, you could specify the minimum guaranteed and maximum usable bandwidth for a traffic class. The order of borrowing of the bandwidth was specified with the prio argument. There’s no prio in HFSC, in favor of time specs.

I must say, that HFSC isn’t documented very well in terms of usage with Linux (and iptables). I spend about three days browsing the web and putting together pieces of information about traffic shaping and HFSC. Finally, I’ve come up with something similar to the wondershaper.

It’s a shell script which sets up the HFSC traffic shaping and works with my ADSL connection. The configuration part is on the front. The body of the script has comments, telling what is being done.

If you’re ready to try, please download the HFSC traffic shaping shell script, edit the beginning to set your connection’s parameters and enjoy!

Author: automatthias

You won't believe what a skeptic I am.

23 thoughts on “HFSC and VoIP”

  1. Hello,

    I’ve setuped more or less my QOS like in your script
    I use a bridge eth0 and eth1 is in br0

    # tc -s -d class show dev eth1

    class hfsc 2: root
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:22 parent 2:2 sc m1 0bit d 10.0s m2 1000Kbit ul m1 0bit d 0us m2 30000Kbit
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:23 parent 2:2 sc m1 0bit d 2.0s m2 1000Kbit ul m1 0bit d 0us m2 30000Kbit
    Sent 3545998683 bytes 2796571 pkts (dropped 299, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:2 parent 2: sc m1 0bit d 0us m2 30000Kbit ul m1 0bit d 0us m2 30000Kbit
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:20 parent 2:2 rt m1 30000Kbit d 50.0ms m2 3000Kbit ls m1 30000Kbit d 50.0ms m2 9000Kbit ul m1 0bit d 0us m2 30000Kbit
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:21 parent 2:2 sc m1 30000Kbit d 200.0ms m2 15000Kbit ul m1 0bit d 0us m2 30000bit
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    class hfsc 2:24 parent 2:2 sc m1 0bit d 20.0s m2 1000Kbit ul m1 0bit d 0us m2 30000Kbit
    Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
    period 24 work 13844803460630839320 bytes rtwork 20444467840 bytes level 3466779352

    As you can see is very strange because the root queue is still 0 nevetheless de the default queue have got a value …

    Maybe you can send me your tc stats report ?

    I would like to discuss with you about your config
    You can contact me by
    mail: scramatte(at)wanado(dot)fr
    skype: scramatte
    msn: scramatte(at)hotmail(dot)com
    jabber: scramatte(at)jabber(dot)org

    regards

  2. Looks like you need a newer tc (from iproute2) as the byte/level counters are garbage.

    Andy.

  3. Hi,

    I’ve been playing around with your HFSC script and I’ve found some issues:
    – cosmetic: the $[] syntax for arithmetics in bash is going to be deprecated soon, use $(()) instead
    – functional: P2P traffic should go into class 1:6, not 1:4 (done in line “for port in $P2PPORTS; do setclassbyport $port 1:4; done”)
    – suggestion: it would be better to specify the device, action and speeds as cmdline parameters

    I’ve already done these modifications to my script and I’d like to send it to you but I can’t seem to find your mail anywhere on this site.

    Best regards!

  4. After reading through your script I may point out an error, i.e. the realtime curves for the interactive and voip classes in the first segment. In both cases, you try to guarantee the full upstream bandwidth to both classes in the initial curve segment, which simply isn’t feasible. Don’t know how the scheduler exactly reacts to such erroneous input, that’s implementation dependent.

    Suffice to say though that the sum of all realtime curves should resp. can’t not exceed the total bandwidth, as the scheduler attempts to actually guarantee realtime curves. Obviously, it can’t guarantee more bandwidth than is available.

    I’m also not sure whether it makes sense to make realtime guarantees to noncritical (like p2p) classes, which you implicitily do with the ‘sc’ command. Defining a link sharing curve should suffice for them, and makes them less likely to interfere with classes which really have realtime demands.

    Regards, B.

    PS: You might also want to check whether you can saturate and fully utilize your uplink with a DSL connection (i.e. ppp device). I noticed that with my 320kbit uplink I had a lot of packet drops and couldn’t saturate, which I finally found out was due to ppp’s default txqueuelen 3. After some experimenting I found that increasing the queue length was suboptimal in my case, but had good results with attaching pfifo limit 10 disciplines to my hsfc classes. Resulted in much less package drops and better bandwidth utilization, at the cost of maybe a slightly increased latency due to this additional queuing. Just a sidenote, anyway.

  5. Thanks for the script. I haven’t downloaded it yet but many thanks for your efforts as you had said that the information for HFSC was lacking and also that you had to piece together what you found from other websites.

    Again many thanks

    Rangi

  6. hi…
    thanks for the script, it works fine. I’ve compared it with wondershaper n the result’s good, so far so good. once again…thanks!

    1. could you help me, how to run it all from beginning to end ?
      i dont know how to use that ..

  7. + tc qdisc add dev imq3 root handle 9:0 hfsc default 2
    + tc class add dev imq3 parent 9: classid 9:1 hfsc sc rate 456kbit ul rate 456kbit
    HFSC: What is “sc” ?
    Usage: … hfsc [ rt SC ] [ ls SC ] [ ul SC ]

    SC := [ [ m1 BPS ] [ d SEC ] m2 BPS

    m1 : slope of first segment
    d : x-coordinate of intersection
    m2 : slope of second segment

    Alternative format:

    SC := [ [ umax BYTE ] dmax SEC ] rate BPS

    umax : maximum unit of work
    dmax : maximum delay
    rate : rate

  8. Hi

    I tried your script on my OpenWRT router because it seems simple and do what I want. I have a strange problem : remote desktop freeze when I use QoS (same problem with the qos-script included in OpenWRT). It works well without QoS even when I am uploading with bittorrent.

    Also, does shaping inbound traffic really works?

  9. Hi Xavier,

    The inbound traffic is the easy one, it should work fine.

    About your remote desktop — I think it’s freezing because traffic shaping scripts you’re using assign low priority to the remote desktop traffic. You could try examining the script and adding the remote desktop port to the high-priority traffic queues.

    At the beginning of the script there is:

    INTERACTIVEPORTS=”22 23 53 3389 5900″

    If your remote desktop traffic is TCP, figure out which port is it using and add that port to the INTERACTIVEPORTS list.

  10. thanx for your script!
    i’ve found out it problematic with lot of uploads going on (when someone i.e. downloads large file from web server running on IP of our connection, and at same time someone tries to i.e. browse the web)

    i’ve fixed this by adding sfq queue on the parent hfsc queue – i hope i’ve done it right.

    also interactivity of web browsing was very sluggish, so i’ve changed limits a bit, added few ports and moved ‘irc’ out of ‘browsing’ class – i tend to talk quite quick over irc 😉

    here is diff :
    mszyca242 hfsc # diff /bin/wondershaper.hfsc hfsc
    26c26
    VOIPIPS=””
    29c29
    INTERACTIVEPORTS=”22 23 53 3389 5900″
    32,33c32,33
    < VOIPPORTS="5060:5100 10000:11000 16300:16800 5000:5059 8000:8016 5004 1720 1731"
    #VOIPPORTS=”5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731″
    > VOIPPORTS=””
    39c39
    P2PPORTS=”110 25 21 143 445 137:139 4662 4664 6881:6999″
    124,125c124,125
    < # Browsing: Don't guarantee anything for 500ms, then
    # Browsing: Don’t guarantee anything for the first second, then
    > # guarantee 1/10
    128c128
    sc m1 0 d 1s m2 $((1*$UPLINK/10))kbit \
    130d129
    < tc qdisc add dev $DEV parent 1:4 handle 4: sfq perturb 2
    198c197
    # them to 6/10 of the downlink.
    203c202
    police rate $((6*${DOWNLINK}/10))kbit \
    210c209
    police rate $((6*${DOWNLINK}/10))kbit \

  11. Hi!
    I’m working on HFSC for my thesis at university.
    May you help me?
    May You tel me how you calculate or plan out the paramenters of HFSC.
    I’m looking for good documentation but I dont find something!!!
    Thanks

    Best regards
    Teresa

    1. hi teresa,
      i confused to use hfsc in linux, i hope you can tell me how i can to do that ? 🙂
      what i supposed to do for the first step ?

      thanks
      sorry if my english isn’t well..

  12. Hello,

    I hate to post to such an old post, but the link to the script is not working. I would appreciate if you could let me know where I can find hfsc.gz

    Thanks.

  13. i can provide you with quick gzip of my personal scripts i have in use :

    http://83.18.229.190/mycelium/hfsc/hfsc_examples.tgz

    besides ‘wondershaper’ you get scripts for additional manual bandwidth limiting :
    ‘przytnij’ means ‘cut/limit’ and ‘odetkaj’ means ‘unclog/remove limit’ while ‘jaco’ is local ‘abusive’ user in my network and ‘wifi’ is public AP
    script starting with ‘przytnij’ are designed to limit bandwith of certain subnet, while ‘odetkaj’ ones remove limits.

    scripts are designed for 2048/256 DSL line with set of private IP’s and single voip phone.

    1. hi Piort,
      i confused to use hfsc in linux, i hope you can tell me how i can to do that ? 🙂
      what i supposed to do for the first step ?

      thanks
      sorry if my english isn’t well..

  14. Hello im a newbie here,
    could you please tell me how to install HFSC in linux platform ?

Comments are closed.