How to slow down traffic with tc?

2

I'm on Ubuntu 14.04; I'd like to learn the basics of traffic shaping, I made a simple script that should slow down my HTTP(S) traffic to ports 80 and 443.

# usage: sudo ./filename.sh

#delete existing rules
# wlan0 is my WiFi
tc qdisc del root dev wlan0

iptables -t mangle -F

echo "Setting.."
# Turn on queuing discipline, enter:
tc qdisc add dev wlan0 root handle 1: htb
tc class add dev wlan0 parent 1: classid 1:1 htb rate 512kbps
# Define a class with limitations:
tc class add dev wlan0 parent 1:1 classid 1:5 htb rate 256kbps ceil 312kbps prio 1
# Define another class with limitations:
tc class add dev wlan0 parent 1:1 classid 1:6 htb rate 256kbps ceil 312kbps prio 0
# Assign it to appropriate qdisc:
tc filter add dev wlan0 parent 1:0 prio 1 protocol ip handle 5 fw flowid 1:5
# Assign it to appropriate qdisc:
tc filter add dev wlan0 parent 1:0 prio 0 protocol ip handle 6 fw flowid 1:6
# Port 80 is NOT defined anywhere in above class. You will use iptables mangle rule as follows:
iptables -A FORWARD -t mangle -p tcp --sport 80 -j MARK --set-mark 5
iptables -A OUTPUT -t mangle -p tcp --sport 80 -j MARK --set-mark 5
# Port 443 is NOT defined anywhere in above class. You will use iptables mangle rule as follows:
iptables -A FORWARD -t mangle -p tcp --sport 443 -j MARK --set-mark 6
iptables -A OUTPUT -t mangle -p tcp --sport 443 -j MARK --set-mark 6
iptables-save

The output is

RTNETLINK answers: No such file or directory
Setting..
# Generated by iptables-save v1.4.21 on Wed Sep  7 08:56:25 2016
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A FORWARD -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x5/0xffffffff
-A FORWARD -p tcp -m tcp --dport 443 -j MARK --set-xmark 0x6/0xffffffff
-A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x5/0xffffffff
-A OUTPUT -p tcp -m tcp --dport 443 -j MARK --set-xmark 0x6/0xffffffff
COMMIT
# Completed on Wed Sep  7 08:56:25 2016

And sudo iptables -t mangle --list:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
MARK       tcp  --  anywhere             anywhere             tcp dpt:http MARK set 0x5
MARK       tcp  --  anywhere             anywhere             tcp dpt:https MARK set 0x6

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
MARK       tcp  --  anywhere             anywhere             tcp dpt:http MARK set 0x5
MARK       tcp  --  anywhere             anywhere             tcp dpt:https MARK set 0x6

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination  

Yet browsering seems still fast, and an Ookla speedtest still gives over 20 Mbps in download and over 30 Mbps in upload.

Am I doing something wrong, or this script is not enough to slow down my connection?

wireless-networking
iptables
network-traffic
traffic-shaping
asked on Super User Sep 7, 2016 by elmazzun

1 Answer

0

I'm not any kind of expert at this, but I had better success with cbq (see below). This version slows everything down, but I'd rather slow down long-running downloads over time while keeping interactive browsing fast. I know I can do that with a proxy server but I'd like to find a way to do it at this level.

rate=64kbps   # 64kbps (512 kbit/sec) = 450 Mb/2 hrs, for each IP address
irate=192kbps # 192kbps allows 490 Gb in 31 days, for the whole interface, max 3 simultaneous downloaders

iface=eth0 # LAN address (could be WiFi)
ranges="192.168.201.128/25"     # 192.168.1.128/255.255.255.128, only slow down DHCP dynamic addresses
alg=cbq # cbq or htb

echo "Throttling hotel network..."

# Clear existing
tc qdisc del dev $iface root 2>&1 | grep -v "No such"

# Limit interface rate
tc qdisc add dev $iface handle 1: root $alg avpkt 1000 bandwidth $irate
tc class add dev $iface parent 1: classid 1:1 $alg rate $rate allot 1500 prio 5 bounded isolated
# Limit rate of each IP address
for range in $ranges; do
        echo "$range"
        tc filter add dev $iface parent 1: protocol ip prio 16 u32 match ip dst $range flowid 1:1
        tc filter add dev $iface parent 1: protocol ip prio 16 u32 match ip src $range flowid 1:1
done
answered on Super User Feb 2, 2017 by Warren Downs

User contributions licensed under CC BY-SA 3.0