Limiting Bandwidth in Linux

The tc command in Linux can be used for fine-grained control over bandwidth throughput. In this case I have limited public outbound traffic to 50Mbps, and internal network traffic to 450Mbps.

The syntax of tc is quite complex. So much so, I found a neat utility called ‘tcng’ (Traffic Control Next Generation) that interprits a much simpler C like syntax and converts it to a string of tc commands.

Here is the tcng script:

dev "eth0" {
  egress {
   class( <$fs> ) // Internal networks
    if ip_dst/22 == 192.168.0.0
    if ip_dst/21 == 192.168.208.0
    if ip_dst/24 == 192.168.240.0
   ;
    class( <$all> ) // All other IP addresses
        if 1
   ;
   htb() {
    class ( rate 500Mbps, ceil 500Mbps ) {
     $fs = class ( rate 450Mbps, ceil 450Mbps ) {sfq;} // Limit internal/trusted network to 450Mbps
     $all = class ( rate 50Mbps, ceil 50Mbps ) {sfq;} // Limit all other networks to 50Mbps
    }
   }
  }
 }

Here is the output it created, which I rolled into a bash script:

# ================================ Device eth0 ================================
tc qdisc add dev eth0 handle 1:0 root dsmark indices 4 default_index 0
tc qdisc add dev eth0 handle 2:0 parent 1:0 htb
tc class add dev eth0 parent 2:0 classid 2:1 htb rate 62500000bps ceil 62500000bps
tc class add dev eth0 parent 2:1 classid 2:2 htb rate 56250000bps ceil 56250000bps
tc qdisc add dev eth0 handle 3:0 parent 2:2 sfq
tc class add dev eth0 parent 2:1 classid 2:3 htb rate 6250000bps ceil 6250000bps
tc qdisc add dev eth0 handle 4:0 parent 2:3 sfq
tc filter add dev eth0 parent 2:0 protocol all prio 1 tcindex mask 0x3 shift 0
tc filter add dev eth0 parent 2:0 protocol all prio 1 handle 2 tcindex classid 2:3
tc filter add dev eth0 parent 2:0 protocol all prio 1 handle 1 tcindex classid 2:2
tc filter add dev eth0 parent 1:0 protocol all prio 1 u32 match u32 0xd055f000 0xfffffc00 at 16 classid 1:1
tc filter add dev eth0 parent 1:0 protocol all prio 1 u32 match u32 0x4a73d000 0xfffff800 at 16 classid 1:1
tc filter add dev eth0 parent 1:0 protocol all prio 1 u32 match u32 0xd109ee00 0xffffff00 at 16 classid 1:1
tc filter add dev eth0 parent 1:0 protocol all prio 1 u32 match u32 0x0 0x0 at 0 classid 1:2

The following command clears out any previous tc settings. You need to run it each time you want to change your traffic limits or configuration:

tc qdisc del root dev eth0

One Response to Limiting Bandwidth in Linux

  1. Ero says:

    Hi.i have a slight problem.i would like to share bandwidth fairly between all resent clients.that is for instance if i have a 100mbps connection and i have 5 clients each should get 20mbps.if more clients come in and the number increases to 10 then each client will get 100mbps/10 = 1 mbs.how do i accomplish this using a script with tc htb or even hfsc?
    Thanks