Wednesday, June 12, 2013

Traffic control in Linux: classifiend and prioritizing traffic 2/2

According to the manual, tc uses the following rules for bandwidth definitions:

mbps = 1024 kbps = 1024 * 1024 bps => byte/s
mbit = 1024 kbit => kilo bit/s.
mb = 1024 kb = 1024 * 1024 b => byte
mbit = 1024 kbit => kilo bit.

Internally, the number is stored in bps and b.

When tc prints the rate, it uses following :

1Mbit = 1024 Kbit = 1024 * 1024 bps => byte/s
The kernel will honor the TOS field in the packets (Type Of Service), which is defined as:

TOS     Bits  Means                    Linux Priority    Band
------------------------------------------------------------
0x0     0     Normal Service           0 Best Effort     1
0x2     1     Minimize Monetary Cost   1 Filler          2
0x4     2     Maximize Reliability     0 Best Effort     1
0x6     3     mmc+mr                   0 Best Effort     1
0x8     4     Maximize Throughput      2 Bulk            2
0xa     5     mmc+mt                   2 Bulk            2
0xc     6     mr+mt                    2 Bulk            2
0xe     7     mmc+mr+mt                2 Bulk            2
0x10    8     Minimize Delay           6 Interactive     0
0x12    9     mmc+md                   6 Interactive     0
0x14    10    mr+md                    6 Interactive     0
0x16    11    mmc+mr+md                6 Interactive     0
0x18    12    mt+md                    4 Int. Bulk       1
0x1a    13    mmc+mt+md                4 Int. Bulk       1
0x1c    14    mr+mt+md                 4 Int. Bulk       1
0x1e    15    mmc+mr+mt+md             4 Int. Bulk       1
As an example, from the RFC 1349 we can see these definitions:

TELNET -> 1000 (8 in decimal) => minimize delay
FTP Control -> 1000 (8 in decimal) => minimize delay
FTP Data -> 0100 (4 in decimal) => maximize throughput
Modifying the TOS field on the traffic we can get our on line games to have priority over the rest of the network : (ok, perhaps some other uses? :)


# iptables -t mangle -N games
# iptables -t mangle -A games -p tcp -s <my playstation ip> -j RETURN
# iptables -t mangle -A games -j TOS --set-tos Maximize-Throughput
# iptables -t mangle -A games -j RETURN
# iptables -t mangle -A POSTROUTING -p tcp -m tos --tos Minimize-Delay -j games
Now, let's put the scenario that we have a Internet line connected to our eth0 with a bandwidth of 10 MBPS. We want to reserve 30% of it to browse internet, 30% for our ftp server and the rest for a online game which uses the port 20000. First we create the qdisc:

# tc qdisc add dev eth0 root handle 1: htb default 90
# tc class add dev eth0 parent 1: classid 1:1 htb rate 10000 kbit ceil 10000 kbit
(we set the root class as 10MBPS)

Next classes will have 30%, 30% and 40% of the bandwidth:
# tc class add dev eth0 parent 1:1 classid 1:10 htb rate 3000kbit ceil 10000kbit
# tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3000kbit ceil 10000 kbit
# tc class add dev eth0 parent 1:1 classid 1:30 htb rate 4000kbit ceil 10000 kbit

Now we will use the Stochastic Fairness Queueing (SFQ) to settle the defined classes. We will use the recommended value of 10 seconds for the queue:

# tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
# tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
# tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10

To finish, we will use the tc to identify traffic for each class (explained in the previous post). Destination port to browse will be 80, source port for our FTP server is 20 and the destination port for the game is 20000:

# tc filter add dev eth0 parent 1:0 protocol ip u32 match ip dport 80 0xffff classid 1:10
# tc filter add dev eth0 parent 1:0 protocol ip u32 match ip sport 20 0xffff classid 1:20
# tc filter add dev eth0 parent 1:0 protocol ip u32 match ip dport 20000 0xffff classid 1:30


That's it. Is interesting to have a look to at the manual for other options like bursting, etc.

4 comments:

  1. Hi Martin,

    Both your articles on 'tc' are very informative and serves interested users a lot as there are not many usage examples of this command on internet.

    I spent past 2-3 hours trying to figure things how tc works but it seems too advance and I do not want to mess-up my configuration. Pls. answer my queries as below and help me out with this situation :

    1). Can we backup and later restore our current settings related to tc, if yes how ?

    2). Can you provide an example which prioritizes http and https traffic over FTP. So when needed http(s) traffic is handled with priority and FTP downloads in background throttled to makeway for it. Also, will ftp resume to use full network capacity after there is no http(s) traffic in queue ?

    Thanks

    ReplyDelete
  2. Hi Deepesh,

    I'm glad you find the post interesting. Regarding to your questions:

    1) Not fully sure on this, but according to the manual if we remove the qdisk from the device then the default disk takes over: (man tc)

    CONFIGURING CLASSLESS QDISCS
    In the absence of classful qdiscs, classless qdiscs can only be attached at the root of a device. Full syntax:

    tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

    To remove, issue

    ***> tc qdisc del dev DEV root

    ***> The pfifo_fast qdisc is the automatic default in the absence of a configured qdisc.

    Then, I would do a script that configures all the tc parameters, or just remove the disk. i.e:

    #!/bin/sh

    if [ ! $1 ]; then
    echo "Missing parameter"
    exit 1
    fi
    interface="eth0"

    case $1 in
    "start")
    echo "Starting qdisk parameters on $interface"
    tc qdisc add dev eth0 root handle 1: htb default 90
    echo "(more parameters to be added)"
    ;;
    "stop")
    echo "Deleting qdisc on $interface"
    tc qdisc del dev $interface root
    ;;
    *)
    echo "Usage: $0 | "
    ;;
    esac


    For the second option, that would be a little more complicated. You would need to configure 3 different classes, one for HTTP, HTTPS and FTP. The FTP would need to be configured with burst, so in case of enough bandwidth available it could use. I never tried but might be something like this (following up the example, and considering the class 1:10 as the FTP):

    tc class add dev wlan0 parent 1: classid 1:1 htb rate 10000kbit ceil 10000kbit

    tc class add dev wlan0 parent 1:1 classid 1:10 htb rate 3000kbit burst 10000kbit ceil 10000kbit

    Hope this helps !

    ReplyDelete
  3. Thanks, I found the one suited for me. A plug-n-play script to do this is - http://www.funtoo.org/Traffic_Control , BTW, I am using Debain wheezy and the rules get overwritten to default every reboot. Any ideas why ?

    ReplyDelete
  4. Where do you keep the rules? I would suggest add them to the /etc/rc.local file so they will be loaded after booting up, or create a startup file in the sysV / upstart init files.

    ReplyDelete