====== 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: **[[http://www.metamorpher.de/files/tc-graph.txt|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