Using TC to Limit Uplink Bandwidth in Linux

Short guide on using TC to force users to obey a certain upload speed in linux.

#First add a 'root' for eth1
tc qdisc add dev eth1 root handle 1: htb default 30
#Second add a class (bucket) with bandwidth restrictions
tc class add dev eth1 parent 1: classid 1:2 htb rate 64kbit
#Then add a filter to force packets through the class
tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 1 fw classid 1:2

tc filter is usually sufficient as it can analyze packets with u32; however, I used iptables for simplicity. I mark a single computer with ip 192.168.0.22.

#Use iptables to tag the packet with a '1' so the filter can 'handle' it
iptables -t mangle -I PREROUTING -s 192.168.0.22/32 -j MARK --set-mark 0x1

Check whether packets are flowing through the class with

 tc -s class show eth1
This entry was posted in Uncategorized and tagged . Bookmark the permalink.

8 Responses to Using TC to Limit Uplink Bandwidth in Linux

  1. Raphael says:

    Hi davychiu,
    I need limit the bandwidth between two virtual machines hosted in the same physical machine. I already try the codes you’ve wrote on this topic and dont work. I ran the command tc both in virtual machines and the physical machine.
    Seems i dont know how to use correctly the tc command.
    I’ve measured the bandwidth between the vm’s with the iperf command.
    Please help me.
    Thanks

    • davychiu says:

      I can’t really help you without more context. If no packets are flowing through the TC class you set up, then it’s configured incorrectly. Make sure your device names reflect your system (eth0, eth1, etc). I suggest also looking through the TC man pages.

  2. Joe says:

    how about i want to bring back my interface to normal, what command show i run?

  3. bhavesh says:

    Hi Davychiu

    I am trying to implement the uplink bandwidth limit on per user basis. Following are the tc commands I am using to do so.

    tc qdisc add dev eth0 root handle 1:0 htb default 10;
    tc class add dev eth0 parent 1:1 classid 1:20 htb rate 512kbps ceil 512kbps;
    iptables -t mangle -A POSTROUTING -o eth0 -s 172.26.1.77 -j CLASSIFY –set-class 1:20;

    So here I want the device with 172.26.1.77 should not get more than 512kbps upload speed.
    And tc -s class show dev eth0 also show packets flowing through it. But the speed test results are always higher than 512kbps.

    Can you please guide me is there anything I am missing out.
    Also the user device is connected to ath1 (wifi interface) and eth0 is connected to physical ethernet cable.
    please let me know if you need any other details.
    Thanks in Advance.

    • davychiu says:

      You need to set the class in PREROUTING. Your users are connected through ath1, so you need to set the limits on ath1 and not eth0.

      • bhavesh says:

        Thanks Davychiu for replying.
        I tried using PREROUTING class and applying the limits on ath1 using following commands but it seems that the packets do not move through the class specified. I mean when we fire tc -s class show dev ath1. It shows 0 packets following through it.

        tc qdisc add dev ath1 root handle 1: htb default 30
        tc class add dev ath1 parent 1: classid 1:2 htb rate 448kbit
        iptables -t mangle -I PREROUTING -s 172.26.1.77/32 -j MARK –set-mark 0x1

Leave a Reply

Your email address will not be published. Required fields are marked *