Ingress Policing with Linux and tc

linux penguinI am simply amazed at the things GNU/Linux can now do, especially with regard to IP networking. I use pf under OpenBSD, a Unix-like operating system that is not Linux, to keep untrusted wireless access traffic from my trusted wired network at home. Lately, I have been working with Linux operating systems in a corporate environment and needed packet policing. It feels good to be able to get similar features to a Cisco device without the need to make a 4500USD purchase.

An ingress policy can decrease the amount of incoming traffic, but it depends on well-behaved TCP/IP stacks and a transport protocol that supports throttling on the sending hosts. The following commands install an ingress queue to eth0 and applies a filter that applies a policy rate of 512kbit.

tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol ip prio 50 \
   u32 match ip src 0.0.0.0/0 police rate 256kbit \
   burst 10k drop flowid :1
tc qdisc add dev eth0 root tbf \
   rate 256kbit latency 25ms burst 10k

Reference Linux Advanced Routing & Traffic Control HOWTO

16 Responses to “Ingress Policing with Linux and tc”

  1. Alex Herington Says:

    Excellent! Works flawlessly. I’d also like to report that this works fine throttling NAT’ed traffic from an ethernet interface to a VLAN interface. *VERY* useful considering I’ve found using tc to limit outgoing traffic on a VLAN interface does *not* work (unless my tests were wrong!).

  2. Steve Says:

    It took me awhile to sit down and wade through documentation, which tended to go through too much theory and background information. The folks that support the Linux Documentation Project are great, and it is through their work that I learned the differences between packet policing and packet shaping. I simply intended this post to serve as a quick howto on setting it up. I’m glad it helped.

  3. Automatthias Says:

    That’s a good approach as it allows people to get some actual results quickly. If someone wants to get deeper into details and get more control, they can always read the papers.

  4. Albert Says:

    Hi There!! There is something that I still don’t get it. Is there a posibility to enqueue incoming traffic and how?

    I can see that the example limits the incoming traffic to a fixed rate. But how could I use a hierarchy of queues to do the job. I read the “Linux Advanced Routing & Traffic Control HOWTO” but I couldn’t figured out how can I enqueue the incoming traffic.

    Thanks for the time.

  5. MockSoul Says:

    Albert, how you can ‘shape’ packets which are already sent? There is no way to shape incoming packets.

  6. Kenny Says:

    The idea is that you slow down the TCP ACKs to the local computer so that it can’t eat up all the incoming bandwidth in the future (not for packets that have already arrived). So instead of a steady stream of packets coming at full speed, you get intervals of silence where the server is waiting for the previous packet to be acknowledged. In those intervals of silence things of higher priority can get a chance to come in.

  7. Lucas Says:

    Hi,

    This don’t work for me.

    I want to limit incoming traffic too, but in this case, the link goes slower and slower, but don’t stay at specific speed.

    at filter, there is a “flowid :1”, but, where is this class There isn’t any class called “:1”, right?

    I did read the lartc, but it’s getting confused.

    If someone can help me, please send me an email.

    lucasmocellin@gmail.com

    Lucas.

  8. shaheem Says:

    thanks i’m gonna try this. how can i give each user an equal amount of BW. ive got some docs but the ones i tried really slow down the server. dunno if this is the norm. it is a mid to low level spec machine tho.

  9. moose Says:

    Thanks for this. Just one question. How can i make these settings permanent so that they will survive a reboot?

  10. Steen Says:

    Save the commands in an executable script, and add a link to this script in your /etc/rc.local file

  11. Greg-Muellerson Says:

    Damn, that sound’s so easy if you think about it.

  12. Kohai Says:

    After hours of working with this thing, it turned out that I needed to increase the burst in order to get it to behave correctly. If you find that you raise the rate but the throughput kB/s doesn’t go up, then increase the burst. I have mine at 50 and my kbit at 2000.

    I did not use the tbf line which one doc I found said it was the preferred method for doing this due to it being network friendly. The tbf line may apply to outbound traffic and the ingress to inbound traffic.

  13. Francois Says:

    I know this blog is old but it helped me out so I just wanted to add a little to it.

    I found that setting the bust to 10% of the rate works for me. So for example to have it limit incoming traffic to 4mbit, I set the bust to 0.4mbit:

    tc filter add dev bond0 parent ffff: protocol ip prio 50 \
    u32 match ip src 0.0.0.0/0 police rate 4mbit \
    burst .4m drop flowid :1

    Thanks for posting this!

  14. z Says:

    Thanks. works for me too

  15. congelli501 Says:

    Thanks for this example, it is simple and effective.

    Do you know if it is possible to add classes for ingress QoS ?
    I want to add an IPv4 and an IPv6 block to a single ingress filter, which doesn’t seem possible without a class.

  16. Manjunath Says:

    Almost 10 year back blog, but trying now. I tried in my router but it is not working for me. Can anyone suggest why it is not working

Leave a Reply