QoS on a Debian transparent bridge with tc

Intro

Here is a way to make QoS on an existent network. First thing to do is to measure the bandwidth of our wan link. Then we will add a Debian bridge just before our wan router. The example will show how to prioritize bandwidth to a remote IP (ex : 169.254.18.10).

Configuration

Installation

Bridge

root@host:~# apt-get install bridge-utils

Interfaces name

Let's change our network interfaces name.

root@host:~# vi /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="b4:83:dc:c2:c4:b8", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="enp*", NAME="lan"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="a8:1b:11:c4:c2:2e", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="enp*", NAME="wan"

Network interfaces configuration

We set permanent bridge and we ask to launch /usr/local/sbin/iptables.sh script once br0 interface is up

root@host:~# vi /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo br0
iface lo inet loopback

iface lan inet manual

iface wan inet manual

iface br0 inet static
bridge_ports lan wan
        address 10.0.0.10
        broadcast 10.0.0.255
        netmask 255.255.255.0
        gateway 10.0.0.254
        up /usr/local/sbin/iptables.sh

QoS script

Here is our QoS script. Let's say we have a 1Mo/s=8Mbit/s=8192kbit/s upload/download bandwidth. I will reserve 5500kbit to 7040kbit for traffic to 169.254.18.10 in upload and download. Default traffic will have 800kbit to 2048kbit. And finally I'll keep bandwidth for ssh traffic.

/usr/local/sbin/iptables.sh

#!/bin/sh
#iptables reset
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

#commands
TC=/usr/bin/tc
IP=/usr/bin/ip

# load modules
modprobe ifb numifbs=2
modprobe sch_fq_codel
modprobe act_mirred
modprobe br_netfilter #in order to netfilter aware about bridge traffic

#QoS reset
for IFB in ifb0 ; do
        $IP link set dev $IFB down
done

for IF in wan ifb0 lan ; do
        $TC qdisc del dev $IF root    2> /dev/null > /dev/null
        $TC qdisc del dev $IF ingress 2> /dev/null > /dev/null
done

iptables -t mangle -F

for IFB in ifb0 ; do
        $IP link set dev $IFB up
done

modemif=wan

#iptables rules if needed
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp -m tos --tos Minimize-Delay -j CLASSIFY --set-class 1:10
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp --dport 53 -j CLASSIFY --set-class 1:10
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp --dport 80 -j CLASSIFY --set-class 1:10
#iptables -t mangle -A PREROUTING -s tcp --dport 443 -j CLASSIFY --set-class 1:10

##############
#UPLOAD RULES#
##############
#RULES
tc qdisc add dev $modemif root handle 1: htb default 10
tc class add dev $modemif parent 1: classid 1:1 htb rate 7600kbit ceil 7600kbit #800kbit #ceil 1500kbit # burst 10k
tc class add dev $modemif parent 1:1 classid 1:10 htb rate 800kbit ceil 2048kbit prio 2 # ceil 2000kbit prio 3 # burst 10k
tc class add dev $modemif parent 1:1 classid 1:12 htb rate 5500kbit ceil 7040kbit prio 1 #ceil 300kbit prio 1
tc class add dev $modemif parent 1:1 classid 1:13 htb rate 80kbit ceil 200kbit prio 3 #ceil 300kbit prio 2

#FILTERS
tc filter add dev $modemif protocol ip parent 1:0 prio 2 u32 match ip sport 22 0xffff flowid 1:13 #ssh traffic
tc filter add dev $modemif protocol ip parent 1:0 prio 2 u32 match ip dport 22 0xffff flowid 1:13 #ssh traffic
tc filter add dev $modemif protocol ip parent 1:0 prio 1 u32 match ip dst 169.254.18.10/32 flowid 1:12  #remote traffic 

## Martin Devera, author of HTB, then recommends SFQ for beneath these classes:
tc qdisc add dev $modemif parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $modemif parent 1:12 handle 20: sfq perturb 10
tc qdisc add dev $modemif parent 1:13 handle 30: sfq perturb 10

################
#DOWNLOAD RULES#
################
#Create ingress on external interface
tc qdisc add dev wan ingress handle ffff:
#Forward all ingress traffic to the IFB device
tc filter add dev wan parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb0

#RULES
tc qdisc add dev ifb0 root handle 2: htb default 10
tc class add dev ifb0 parent 2: classid 2:1 htb rate 7600kbit ceil 7600kbit
tc class add dev ifb0 parent 2:1 classid 2:10 htb rate 800kbit ceil 2048kbit prio 3
tc class add dev ifb0 parent 2:1 classid 2:12 htb rate 5500kbit ceil 7040kbit prio 1
tc class add dev ifb0 parent 2:1 classid 2:13 htb rate 80kbit ceil 200kbit prio 2

#FILTERS
tc filter add dev ifb0 protocol ip parent 2:0 prio 1 u32 match ip src 169.254.18.10/32 flowid 2:12  #traffic 
tc filter add dev ifb0 protocol ip parent 2:0 prio 2 u32 match ip sport 22 0xffff flowid 2:13    #ssh traffic 
tc filter add dev ifb0 protocol ip parent 2:0 prio 2 u32 match ip dport 22 0xffff flowid 2:13    #ssh traffic

Useful commands

root@host:~# tc -s class ls dev wan
root@host:~# tc -s qdisc ls dev wan
root@host:~# tc qdisc show
root@host:~# tc qdisc show dev wan
root@host:~# tc filter show dev wan
root@host:~# tc qdisc del dev wan root

Source : https://www.funtoo.org/Traffic_Control ; Gentoo Wiki

Licence Creative Commons
This website http://shebangthedolphins.net is licensed to the public under a licence Creative Commons Attribution licence.
Contact :