Penguin
Note: You are viewing an old revision of this page. View the current version.

This is my first attempt and writing something up about traffic shaping. I don't really understand much how this works, but I'm going to document a bit in the hope that people can improve it.

This is a script I use to throttle one machine down to half our ADSL rate. This machine is used for downloading large files (for example .iso's of the latest LinuxDistribution), but we don't want it impacting the rest of our machines. This example was stolen from the Advanced Router HOWTO, and cleaned up a bit by me.

You run this script on your gateway rate limiting data to your internal client machine(s).

  1. /bin/sh

  2. The device data is going out of. You can't stop a machine recieving data (short of firewalling)
  3. But you can limit how fast it sends data.

DEV=eth0

  1. The IP you want to throttle

IP=10.10.10.13

  1. How fast your internal network is. This is used to estimate the rates more accurately. If this
  2. is wrong then the rate will be out by a little bit or something.

LINERATE=100mbit

  1. How fast you want them to be able to d/l at. "kbps" means "kilobytes per second", don't get it
  2. confused with "kbits" which is approximately 10 times slower :)

THROTTLERATE=15kbps

  1. Where the tc executable is.

TC=/sbin/tc

if ! -x $TC?; then

echo Cant find $TC, aborting exit 1

fi

  1. Remove any previous queuing. This probably removes any other policies you have on this interface
  2. too. Oh well.

$TC qdisc del dev $DEV root 2>/dev/null

  1. Add a Queuing Discipline. A Queuing discipline is what manages the queues.
  2. we're using the "cbq" discipline, and we're saying that the average packet size is 1000 bytes
  3. (probably completely wrong :) Once again this is just a parameter to make it more accurate.

$TC qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth $LINERATE

  1. Create a class, also(?) a cbq, rate limited to $THROTTLERATE. allot I Think is how much
  2. data they get before they are rate limited. This must be at least the MTU (since you can't
  3. send partial packets you must be able to send at least one entire packet).
  4. I don't know what "prio" is about.
  5. bounded means that it cannot exceed this rate, if this was left off, I think it means that
  6. when the link is saturated that this can't use more than $THROTTLERATE and everyone else can
  7. share the rest. An example use of this might be to set $THROTTLERATE to 0 and remove bounded
  8. meaning that everything else can use the link in preference. I think.
  9. Isolated I'm not sure about, I think it means it doesn't interact with any other rules.

$TC class add dev $DEV parent 1: classid 1:1 cbq rate $THROTTLERATE \

allot 1500 prio 5 bounded isolated

  1. Add a filter to go into this class.
  2. This uses the "u32" filter which matches based on header fields in the IP packet.
  3. If you want to match on multiple rules you can use "match ip dest $IP src $IP" etc. I don't
  4. know how you do not. I think if you want to do anything interesting with TC you probably want
  5. to use fwmark from iptables(8).

$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \

match ip dst $IP flowid 1:1

  1. Peturb the random hash every 10s
  2. Ok, what cbq does (I think) is put everything into buckets based on a hash function. However
  3. sometimes you end up with hash collisions meaning that data will be occasionally lumped together
  4. with other data and they will both be rate limited as if they were one connection. The way
  5. around this is to change the hash function frequently so that this effect is reduced. However
  6. doing this too often makes your rate limiting less accurate, doing it too rarely means that
  7. data is incorrectly classified as above, so we tell the kernel to change the hash every 10s.

$TC qdisc add dev $DEV parent 1:1 sfq perturb 10

Hopefully this is enough to get people started, please, if you know anything more add it to this page. I found the advanced router howto very oblique in it's information.