Table of Contents

Traffic control

Il traffic control viene fatto in genere su una egress qdisc (queue discipline su traffico in uscita). Sul traffico in ingresso (ingress) c'è poco da fare, si può attaccare solo un policer (cioè il pacchetti che superano un certo limite vengono scartati).

tc-graph.pl

tc-graph.pl è un tool che genera un grafio delle regole TC collegate ad una interfaccia (queue disciplines, classese e filters). L'utility si scarica da qui: tc-graph.pl. Si deve modificare lo script impostando il nome dell'interfaccia su cui lavora, lo si esegue ottenendo un file .dot, questo file viene dato in pasto al programma dot (facente parte del pacchetto graphviz) per ottenere un'immagine:

perl tc-graph.pl > mygraph.dot
cat mygraph.dot | dot -Tpng > mygraph.png

Traffic control with Shorewall

We use the traffic control tools included with Shorewall, those are the kernel modules nedded:

Kernel module Note
sch_sfq Stochastic Fairness Queuing: it tries to track connections (tcp or udp streams) and balances the traffic between them.
sch_htb Hierarchical Token Bucket: allows to define a set of classes, and put the traffic into these classes. Can define minimum and maximum bandwitdh settings for those classes and order them hierachically.
sch_ingress
cls_u32

Shorewall builtin traffic shaping allows you to define these classes (and their bandwidth limits), and it uses SFQ inside these classes to make sure that different data streams are handled equally.

First experiment with traffic control

Kernel modules

Kernel module Note
sch_prio For the “PRIO” classful qdisc
sch_tbf For the “tbf” classless qdisc
cls_fw For the “fw” classifier (filter based on iptables mark)
ipt_MARK For netfilter target “MARK”
#!/bin/sh
 
#-------------------------------------------------------------------------#
# We will replace the default queue discipline attached to device eth0.   #
# The default qdisc is a pfifo_fast (first in, first out); we will use a  #
# PRIO qdisc instead, which can classify packets by priority.             #
#                                                                         #
#       1:0       root PRIO qdisc                                         #
#      / | \                                                              #
#    /   |   \                                                            #
#  1:1  1:2  1:3  The PRIO qdisc has three classes by default.            #
#             |                                                           #
#           30:0  leaf Token Bucket Filter (tbf) qdisc                    #
#                                                                         #
#                                                                         #
# Class 1:1 and 1:2 have a default pfifo_fast qdisc.                      #
# Class 1:3 has a shaping discipline attached instead; the tbf qdisc, to  #
# limit bandwidth usage.                                                  #
#                                                                         #
# When a packet arrives, it is enqueued by default to 1:1 unless it is    #
# classified by a filter to 1:2 or 1:3.                                   #
# When a packet is requested for dequeueing, 1:1, 1:2 or 30:0 are         #
# searched in turn.                                                       #
#                                                                         #
# Using filters based on fwmark we will send low-priority traffic to 1:2, #
# low-priority traffic that also need to be shaped will be sent to 30:0.  #
#                                                                         #
#-------------------------------------------------------------------------#
 
case "$1" in
    start)
 
 
        #-----------------------------------------------------------------
        # Insert required kernel modules.
        #-----------------------------------------------------------------
        insmod sch_prio  # Needed for the "PRIO" classful qdisc.
        insmod sch_tbf   # Needed for the "tbf" classless qdisc.
        insmod cls_fw    # Needed for the "fw" classifier (filter based on iptables mark).
        insmod ipt_MARK  # Needed for netfilter target "MARK".
 
 
        #-----------------------------------------------------------------
        # Substitute the default root qdisc for eth0 with a PRIO qdisc.
        # This PRIO qdisc will have 3 classes by default 1:1, 1:2 and 1:3.
        #-----------------------------------------------------------------
        tc qdisc add dev eth0 root handle 1:0 prio
 
 
        #-----------------------------------------------------------------
        # Attach a Token Bucket Filter shaper to class 3 of PRIO 1:0.
        #-----------------------------------------------------------------
        tc qdisc add dev eth0 parent 1:3 handle 30:0 tbf rate 128kbit burst 2kb latency 70ms
 
 
        #-----------------------------------------------------------------
        # Add classifiers (filters) based on iptables mark.
        #-----------------------------------------------------------------
 
        # Packets marked with fwmark 3 will go to class 1:3 where
        # there is the tbf, with shaped bandwidth.
        tc filter add dev eth0 parent 1:0 prio 1 protocol ip fw handle 3 flowid 1:3
 
        # Packets marked with fwmark 2 will go to class 1:2 where
        # there is the default pfifo_fast. Packets from here will be
        # dequeued with a lower priority than from default class 1:1.
        tc filter add dev eth0 parent 1:0 prio 2 protocol ip fw handle 2 flowid 1:2
 
 
        #-----------------------------------------------------------------
        # Add some iptables rule to mark packets.
        #-----------------------------------------------------------------
        iptables -A PREROUTING -t mangle --protocol tcp --source-port 80 -j MARK --set-mark 3
 
        ;;
 
    stop)
        # Undo everything was done by the "start" target.
        iptables -D PREROUTING -t mangle --protocol tcp --source-port 80 -j MARK --set-mark 30
        tc filter del dev eth0 parent 1:0 protocol ip prio 1 fw
        tc filter del dev eth0 parent 1:0 protocol ip prio 2 fw
        tc qdisc  del dev eth0 parent 1:3 handle 30:0 tbf
        tc qdisc  del dev eth0 root handle 1:0 prio
        rmmod ipt_MARK
        rmmod cls_fw
        rmmod sch_tbf
        rmmod sch_prio
        ;;
 
    status)
        echo '#-------------------------------------------------'
        echo '# Qdisc for device eth0'
        echo '#-------------------------------------------------'
        tc qdisc show dev eth0
        echo
        echo '#-------------------------------------------------'
        echo '# Classes for qdisc PRIO 1:0'
        echo '#-------------------------------------------------'
        tc class show dev eth0 parent 1:0
        echo
        echo '#-------------------------------------------------'
        echo '# Classifiers for qdisc PRIO 1:0'
        echo '#-------------------------------------------------'
        tc filter show dev eth0
        echo
        echo '#-------------------------------------------------'
        echo '# Statistics about packets and qdisc'
        echo '#-------------------------------------------------'
        tc -s qdisc show dev eth0
        ;;
 
    *)
        echo "Usage: $0 {start|stop|status}"
        exit 1
        ;;
 
esac