The script blow tries to limit the incoming rate of the port 2000, when using iptables
to mark the INPUT
packets does not work, but OUTPUT
works fine.
I use nc -kl 2000
on machine 10.0.1.54
and iperf -c 10.0.1.54 -p 2000 -t 10
on another machine to test it.
Why OUTPUT
works but not INPUT
?
dev=enp3s0
ip_addr=10.0.1.54
ip_port=2000
rate_limit=20kbit
htb_class=10
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_limit
tc filter add dev $dev parent 1: prio 0 protocol ip handle $htb_class fw flowid 1:$htb_class
# marking the INPUT chain does dot work as expected
#iptables -t mangle -A INPUT -d $ip_addr -p tcp --dport $ip_port -j MARK --set-mark $htb_class
# marking the OUTPUT chain works fine
iptables -t mangle -A OUTPUT -s $ip_addr -p tcp --sport $ip_port -j MARK --set-mark $htb_class
elif [ "$1" = "disable" ]; then
echo "disabling rate limits"
tc qdisc del dev $dev root > /dev/null 2>&1
#iptables -t mangle -D INPUT -d $ip_addr -p tcp --dport $ip_port -j MARK --set-mark $htb_class
iptables -t mangle -D OUTPUT -s $ip_addr -p tcp --sport $ip_port -j MARK --set-mark $htb_class
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