How can I identify download traffic and set a mark so that I can route those packets using the fwmark through another link ?
-
2I believe this question, as it stands, is too big to reasonably answer. You should update with some specifics.– Scott PackCommented Mar 20, 2011 at 14:44
-
You really need to start by defining "downloads". Technically, everything the comes into your network from the Internet is download traffic.– John GardeniersCommented Mar 20, 2011 at 20:35
-
Here "download" means files that are being downloaded more than 1MB size. I want to mark such traffic and route them to another link (ISP connection) using iproute2– SupratikCommented Mar 21, 2011 at 5:01
2 Answers
The iptables modules connbytes, connlimit and length can be used to identify downloads. Here the setup is use:
#Mark downloads
$IPT -t mangle -N BULKCONN
#Small packet is probably interactive or flow control
$IPT -t mangle -A BULKCONN -m length --length 0:500 -j RETURN
#Small packet connections: multi purpose (don't harm since not maxed out)
$IPT -t mangle -A BULKCONN -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j RETURN
#After one megabyte a connection is considered a download
$IPT -t mangle -A BULKCONN -m connbytes --connbytes 1048576: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 6
$IPT -t mangle -A BULKCONN -j RETURN
$IPT -t mangle -A PREROUTING -i eth1 -j BULKCONN
I use queuing disciplines to prioritize downloads and other traffic.
About sending through another link: I am not ready to answer this, but it would be done with iproute2 (assuming you mean another IP link). However it will only work downstream, since you can not control where upstream traffic reaches you.
-
@Ganwell thanks for providing this wonderful solution. Yes I am using iproute2 to route packets to another link (other ISP connection). I found that the modules connbytes and connlimit is not present with the kernel. Is there any easy way to include this modules without recompiling the kernel ?– SupratikCommented Mar 21, 2011 at 4:58
-
@Supratik It is in the mainstream kernel since 2.6.16, maybe you can update the kernel. It is possible to add modules but usually it is as complicated as compiling the whole kernel. What is your kernels version and what distribution are you using?– GanwellCommented Mar 21, 2011 at 12:44
-
@Ganwell thanks for the reply. I am using kernel-2.6.18-194.3.1.el5 and I am using CentOS 5. I am getting "Couldn't load match `connbytes':/lib/iptables/libipt_connbytes.so" error. Can you please advice how should I proceed ?– SupratikCommented Mar 21, 2011 at 14:42
-
@Supratik Wow that is outdated (from 2006). It seems that the CentOSPlus repo has newer kernels. Unfortunately I use this other distribution and I can only tell that I never had any problems when upgrading kernels there. Maybe you can test it on a other box first: Clone your system and do the upgrade, if everything works and connbytes is available, do it on the hot system.– GanwellCommented Mar 21, 2011 at 16:04
-
@Supratik No newer kernels in CentOSPlus. A fresh install is generally strongly preferred over an upgrade. <- Probably you should switch to a upgradable distribution. From MigrationGuide– GanwellCommented Mar 21, 2011 at 16:17
I was inspired by @Ganwell solution to this, and managed to solve this on top of adding in a tc
classful traffic shaping. I blogged about this solution in my personal wiki: https://giki.wiki/@nubela/Software-Engineering/Per-Connection-Throttling
Here's my solution to this question with an actual shell script:
#!/bin/sh
dev=eth0
ip_port=3002
rate_limit=512kbit
rate_ceil=1024kbit
htb_class=10
max_byte=10485760
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
if [ "$1" = "enable" ]; then
echo "enabling rate limits"
tc qdisc del dev $dev root > /dev/null 2>&1
tc qdisc add dev $dev root handle 1: htb
tc class add dev $dev parent 1: classid 1:$htb_class htb rate $rate_limit ceil $rate_ceil
tc filter add dev $dev parent 1: prio 0 protocol ip handle $htb_class fw flowid 1:$htb_class
#iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -j MARK --set-mark $htb_class
# small packet is probably interactive or flow control
iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m length --length 0:500 -j RETURN
# small packet connections: multi purpose (don't harm since not maxed out)
iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j RETURN
#after 10 megabyte a connection is considered a download
iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes $max_byte: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark $htb_class
iptables -t mangle -A OUTPUT -j RETURN
elif [ "$1" = "disable" ]; then
echo "disabling rate limits"
tc qdisc del dev $dev root > /dev/null 2>&1
iptables -t mangle -F
iptables -t mangle -X
elif [ "$1" = "show" ]; then
tc qdisc show dev $dev
tc class show dev $dev
tc filter show dev $dev
iptables -t mangle -vnL INPUT
iptables -t mangle -vnL OUTPUT
else
echo "invalid arg $1"
fi