Wednesday, September 21, 2011

Outbound bandwidth limit

Came across this nice tool called 'tc' which allows us to put a bandwidth limit for outgoing traffic.

I had this challenge of limiting the bandwidth for outbound traffic which is originated from our server. I did some search on Internet and came up with below settings to be put in firewall rule.

1. First of all, we need to add qdisc to our outbound interface through which traffic is going to go out.
# /sbin/tc qdisc add dev $IFACE root handle 1:0 htb default 0

You can learn about tc through howto's available on the Internet. This command line is basically telling kernel that unclassified traffic should not be applied the bandwidth limit at all (There is no default 0 class as such, so all unclassified traffic will obviously have no limit. In my case, the traffic in response to incoming request, such as rendering of html pages etc).

2. Create a class for every outgoing port allowed. The traffic originated from the server is the one with destination port as any of the standard service port which we allow anyway like 80, 3306 etc. This can be used as a criterion to distinguish traffic originated from server and the traffic in response to client's request. Though there are other sophisticated ways to identify traffic originated from server like iptables connmark module, for now this basic assumption is working for
us.

# /sbin/tc class add dev $IFACE parent 1:0 classid 1:$CLASS_ID htb rate 5mbit ceil 5mbit

3. Using the iptables, mark all kinds of outgoing traffic which we want to apply bandwidth limit on.

# /sbin/iptables -t mangle -A OUTPUT -p tcp --dport $port -j MARK --set-mark $CLASS_ID


4. Now finally, you have to associate marked packets to the various classes so that actual bandwidth limit takes place.

# /sbin/tc filter add dev $IFACE parent 1:0 prio 0 protocol ip handle $CLASS_ID fw flowid 1:$CLASS_ID



Now that you have all set, you want to check the stats, you can use below commands.

1. Check stats related to class

# tc -s -d class show dev $IFACE

2. Check filter stats.

# tc filter show dev $IFACE