IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Vegeu també Qualitat de Servei

Introducció

Traffic shaping ( aka packet shaping) is a computer network traffic management technique which delays some or all datagrams to bring them into compliance with a desired traffic profile.[1][2] Traffic shaping is a form of rate limiting.

Traffic shaping is used to optimize or guarantee performance, improve latency, and/or increase usable bandwidth for some kinds of packets by delaying other kinds.

Recursos:


tc

TC són les inicials de Traffic Control aka control del trànsit en català. L'ordre tc (/sbin/tc) pertany al paquet iproute:

$ dpkg -S /sbin/tc
iproute: /sbin/tc

Tc són les inicials de Traffic Control. Amb l'ordre tc és gestiona el control de trànsit que realitza el nucli (Linux) del sistema operatiu. El control del trànsit consisteix en:

  • SHAPING: és diu que el trànsit està shaped quan la tasa de transmissió (rate) està supervisada. Cal tenir en compte que el shaping pot ser més que no només limitar l'ampla de banda, també s'utilitza per suavitzar les ràfagues de transit o bursts. El shaping sempre succeix al egress
  • SCHEDULING: al planificar la transmissió de paquets és possible millorar el trànsit interactiu o trànsit que necessita treballar en temps real al mateix temps que es garanteix ambpla de banda per als bulk transfers. També es coneix com reordering o priorització. També succeix només a egress
  • POLICING: Similar al shaping però per al trànsit d'arrivada. Policing succeix a ingress.
  • DROPPING: el trànsit que supera un cert ampla de banda pot ser droped tant en ingress com en egress.

El controls del trànsit el realitzen tres tipus d'objectes:

  • qdiscs: qdisc és l'abreviació de queueing discipline i és un concepte elemental per entendre el traffic control. Cada cop que el kernel necessita enviar un paquet a una interfície de xarxa, el paquet s'envia a la cua configurada per a a aquesta interfície. Immediatament despreés el kernel intenta obtenir tants paques com pugui d'aquesta qdisc per tal que siguin enviats al adaptador de xarxa. La qdisc més simple és la pfifo o paquet fifo, és a dir una cua on els paquets que surten primer per la itnerfície són els que arriben primers (first in first out), cal tenir en compte que les cues fifo també fan de cache temporal.
  • classes: algunes qdiscs poden contenir classes, les quals també poden contenir altres qdiscs. Les qdiscs amb classes es coneixen també com classful qdiscs i les que no tenen classes com a classles qdiscs. Quan el nucli mira de treure de la cua un paquet, si el paquets ve d'una classful qdisc aleshores el paquets es pot obtenir de qualsevol de les classes que formen la qdisc. És un mecanisme per crear ques complexes compostes per grups de cues o classes. Per exemples, una qdisc pot prioritzar certs tipus de trànsit mirant de treure els paquets abans de certes classes abans que d'altres.
  • filters: els filtres els utilitzen les classful qdisc per tal determinar en quina classe cal encuar un paquet concret. Cada cop que un paquet arriba classe amb subclasses es necessari classificar aquest paquet. Es poden utilitzar diversos mètodes, un mecanisme és els filtres. Tots els filtres associats a una classe s'executen en ordre fins que un d'ells s'apliqui, si cap s'aplica aleshores es poden aplicar altres criteris que no siguin els filtres.

Sintaxi i ús

Vegem la sintaxi general:

$ tc
Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }
where  OBJECT := { qdisc | class | filter }
       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }
  

Com podeu veure hi ha 3 objectes:

Cada objecte accepta diferents opcions i es poden consultar amb la sintaxi:

$ tc qdisc help
Usage: tc qdisc [ add | del | replace | change | show ] dev STRING
      [ handle QHANDLE ] [ root | ingress | parent CLASSID ]
      [ estimator INTERVAL TIME_CONSTANT ]
      [ stab [ help | STAB_OPTIONS] ]
      [ [ QDISC_KIND ] [ help | OPTIONS ] ]

      tc qdisc show [ dev STRING ] [ingress]
Where:
QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }
OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help
STAB_OPTIONS := ... try tc qdisc add stab help

Per llistar les disciplines de cua no poseu res:

$ tc qdisc
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

Per defecte pfifo_fast com podeu observar. També podeu escriure:

$ tc qdisc list

Veiem un exemple concret de disciplina de cua:

$ tc qdisc add    \ 
                  dev eth0     \ 
                  root         \ 
                  handle 1:0   \ 
                  htb            

En aquest cas estem afegint una disciplina de cua. Observeu:

dev eth0  

Especifica el dispositiu de xarxa a on s'aplica la cua.

NOTA: Recordeu que les normes s'apliquen sempre a la cua de sortida egress

Després observeu:

root

root no és l'usuari sinó la cua, és a dir la cua arrel, la principal. Amb això estem afegint una cua principal al dispositiu de xarxa eth0.

La següent part és el handle. El handle té la sintaxi:

major:minor

El minor number per a qualsevol disciplina de cua és sempre 0 (zero). S'accepta la sintaxi:

1:

On se suposa que minor val 0.

Finalment s'especifica el tipus de cua. A l'exemple Hierachical Token Bucket:

HTB 

Seguit del tipus de cua poden haver-hi paràmetres específics del tipus de cua. Si no s'indica res s'apliquen els valors per defecte.

Veiem ara un exemple de class:

 $ tc class add    \ 
                  dev eth0     \ 
                  parent 1:1   \ 
                  classid 1:6  \ 
                  htb          \ 
                  rate 256kbit \ 
                  ceil 512kbit   
     

Specify the device onto which we are attaching the new class.


Specify the parent handle to which we are attaching the new class.


This is a unique handle (major:minor) identifying this class. The minor number must be any non-zero (0) number.


Both of the classful qdiscs require that any children classes be classes of the same type as the parent. Thus an HTB qdisc will contain HTB classes.


This is a class specific parameter. Consult Section 7.1 for more detail on these parameters.

Example 5. tc filter


[[email protected]]# tc filter add \ > dev eth0 \ > parent 1:0 \ > protocol ip \ > prio 5 \ > u32 \ > match ip port 22 0xffff \ > match ip tos 0x10 0xff \ > flowid 1:6 \ > police \ > rate 32000bps \ (11) > burst 10240 \ (12) > mpu 0 \ (13) > action drop/continue (14)


Add a filter. The verb could also be del.


Specify the device onto which we are attaching the new filter.


Specify the parent handle to which we are attaching the new filter.


This parameter is required. It's use should be obvious, although I don't know more.


The prio parameter allows a given filter to be preferred above another. The pref is a synonym.


This is a classifier, and is a required phrase in every tc filter command.


These are parameters to the classifier. In this case, packets with a type of service flag (indicating interactive usage) and matching port 22 will be selected by this statement.


The flowid specifies the handle of the target class (or qdisc) to which a matching filter should send its selected packets.


This is the policer, and is an optional phrase in every tc filter command.

(11)

The policer will perform one action above this rate, and another action below (see action parameter).

(12)

The burst is an exact analog to burst in HTB (burst is a buckets concept).

(13)

The minimum policed unit. To count all traffic, use an mpu of zero (0).

(14)

The action indicates what should be done if the rate based on the attributes of the policer. The first word specifies the action to take if the policer has been exceeded. The second word specifies action to take otherwise.
As evidenced above, the tc command line utility has an arcane and complex syntax, even for simple operations such as these examples show. It should come as no surprised to the reader that there exists an easier way to configure Linux traffic control. See the next section, Section 5.3.
Mostrar estadístiques i detalls

Es poden utilitzar les opcions:

-s, -stats, -statistics
             output more statistics about packet usage.

-d, -details
             output more detailed information about rates and cell sizes.

Un exemple:

$ watch tc -s -d qdisc show
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 646455196 bytes 4271110 pkt (dropped 0, overlimits 0 requeues 1) 
backlog 0b 0p requeues 1

Classless qdiscs

Es disposa de les següents disciplines de cua sense classes:

  • [p|b]fifo: són dos possibles bfifo i pfifo és la disciplina de cua més simple, una disciplina amb un comportament purament FIFO. La p i la b indiquen si la cua està limitada en nombre de paquets o en nombre de bytes.
  • pfifo_fast: és la disciplina de cua que s'utilitza per defecte en kernels amb Advanced Router activat. És una qua FIFO three-band que suporta els flags Type of Service per prioritzar trànsit.
  • red: Random Early Detection permet simular congestió física del traǹsit eliminant (dropping) paquets de forma aleatòria. TODO: "randomly dropping packets when nearing configured bandwidth allocation. Well suited to very large bandwidth applications."
  • sfq: Stochastic Fairness Queueing reordena el trànsit encuat per a cada sessió de forma que cada sessió envia un paquet seguin una round robin, és a dir un paquet per torn i sessió.
  • tbf: TEl filtre Token Bucket Filter està pensat per a disminuir el transit a una velocitat o rate predefinit.

Exemple cua bfifo

Vegem un exemple:

$ tc qdisc add dev eth0 handle 1:0 root dsmark indices 1 default_index 0
$ tc qdisc add dev eth0 handle 2:0 parent 1:0 bfifo limit 1024

Crea una cua bfifo de 10kbyte

Classful qdiscs

Les disciplines de cua amb classes són:

  • CBQ (aka Class Based Queueing): implementa una jeràrquia de classes rich linksharing. Conté tant elements de shaping com de priorització de trànsit. El Shaping es realitza utilitzant càlculs del link idle time basats en la mitjana (average) de la mida dels paquets i l'ampla de banda disponibles a la interfície física. TODO: The latter may be ill-defined for some interfaces.
  • HTB (aka Hierarchy Token Bucket): també implementa una jeràrquia de classes rich linksharing posant emfàsis en adaptar-se a les pràctiques ja existents. HTB facilita el garantir cert ampla de banda a les classes alhora que permet indicar límits superiors al inter-class sharing. Conté elements de shaping en TBF i pot prioritzar classes.
  • PRIO : la disciplina de cua PRIO és un contenidor que no realitzar shaping per a un nombre de classes configurables que són desencuades en ordre. Això permet prioritzar trànsit de forma fàcil ja que les classes inferiors només poden enviar trànsit si les superiors no tenen paquets disponibles per enviar. Per facilitar la configuració, el camp Type Of Service és gestiona segons els estandards per defecte (honored by default)

Com funciona?

Les classes formen un arbre (tree) on cada classe té un sol pare i pot tenir cap o mútiples classes filles. Algunes disciplines de cua permeten afegir classes en temps d'execució (p.ex. CBQ i HTB) i en canvi altres (PRIO) es creen amb uin nombre estàtic de fills.

Qdiscs which allow dynamic addition of classes can have zero or more subclasses to which traffic may be enqueued.

A més, cada classe conté una disciplina de cua fulla (és a dir, una qdisc sense classes filles) aka leaf qdisc que per defecte té un comportament pfifo. Es poden però modificar les leaf qdisc per aplicar altres polítiques per defecte.

Quan un paquet entra en una classful qdisc el paquet s'ha de classificar a una de les subclasses, seguin algun dels següents criteris (algunes qdist no utilitzen totes les opcions):

  • tc filters: si s'han definit filtres associats a la classe, són el primer que es consulta. Els filtres es poden fixar en qualsevol dels camps de la capçalera del paquet així com en marques del firewall iptables ( firewall mark)
  • Type of Service: algunes disciplines de cua tenen normes builtin que permeten classificar els paquets segons el camp TOS.
  • skb->priority: els programes de espai d'usuari (user-space) poden codificar un identificador de classe o class-id al camp 'skb->priority' utilitzant l'opció SO_PRIORITY.

Cada node de l'arbre pot tenir els seus propis filtres però cal tenir en compte que ls filtres que s'apliqune en nivells de l'arbre superiors pode apuntar directament a classes inferiors saltant-se part de l'arbre.point directly to lower classes.

Si la classificació no es duu a terme segons cap dels criteris anteriors, aleshores s'aplica la leaf qdisc associada a la classe. Es poden consultar els manuals de cada tipus de qdisc per a veure els detalls (vegeu tc-htb, tc-cbq...)

TODO

SEE ALSO

      tc-cbq(8), tc-choke(8), tc-drr(8), tc-htb(8), tc-hfsc(8), tc-hfsc(7), tc-sfq(8), tc-red(8), tc-tbf(8), tc-pfifo(8), tc-bfifo(8), tc-pfifo_fast(8), tc-stab(8),
      User documentation at http://lartc.org/, but please direct bugreports and patches to: <[email protected]>

Sintaxi i funcionament

SYNOPSIS

      tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]
      tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]
      tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id
      tc [ FORMAT ] qdisc show [ dev DEV ]
      tc [ FORMAT ] class show dev DEV
      tc filter show dev DEV

FORMAT := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | i[ec] }

TC COMMANDS

      The following commands are available for qdiscs, classes and filter:
      add    Add a qdisc, class or filter to a node. For all entities, a parent must be passed, either by passing its ID or by attaching directly to the root of a device.  When creating a qdisc or a
             filter, it can be named with the handle parameter. A class is named with the classid parameter.
      remove A qdisc can be removed by specifying its handle, which may also be 'root'. All subclasses and their leaf qdiscs are automatically deleted, as well as any filters attached to them.
      change Some entities can be modified 'in place'. Shares the syntax of 'add', with the exception that the handle cannot be changed and neither can the parent. In other words, change cannot move
             a node.
      replace
             Performs a nearly atomic remove/add on an existing node id. If the node does not exist yet it is created.
      link   Only available for qdiscs and performs a replace where the node must exist already.

NAMING

      All qdiscs, classes and filters have IDs, which can either be specified or be automatically assigned.
      IDs consist of a major number and a minor number, separated by a colon.
      QDISCS A qdisc, which potentially can have children, gets assigned a major number, called a 'handle', leaving the minor number namespace available for  classes.  The  handle  is  expressed  as
             '10:'.  It is customary to explicitly assign a handle to qdiscs expected to have children.
      CLASSES
             Classes  residing under a qdisc share their qdisc major number, but each have a separate minor number called a 'classid' that has no relation to their parent classes, only to their par‐
             ent qdisc. The same naming custom as for qdiscs applies.
      FILTERS
             Filters have a three part ID, which is only needed when using a hashed filter hierarchy.

UNITS

      All parameters accept a floating point number, possibly followed by a unit.
      Bandwidths or rates can be specified in:
      kbps   Kilobytes per second
      mbps   Megabytes per second
      kbit   Kilobits per second
      mbit   Megabits per second
      bps or a bare number
             Bytes per second
      Amounts of data can be specified in:
      kb or k
             Kilobytes
      mb or m
             Megabytes
      mbit   Megabits
      kbit   Kilobits
      b or a bare number
             Bytes.
      Lengths of time can be specified in:
      s, sec or secs
             Whole seconds
 ms, msec or msecs
             Milliseconds
      us, usec, usecs or a bare number
             Microseconds.

FORMAT

      The show command has additional formatting options:
      -s, -stats, -statistics
             output more statistics about packet usage.
      -d, -details
             output more detailed information about rates and cell sizes.
      -r, -raw
             output raw hex values for handles.
      -p, -pretty
             decode filter offset and mask values to equivalent filter commands based on TCP/IP.
      -iec   print rates in IEC units (ie. 1K = 1024).



Documentació

Manual
$ man tc

netem

netem són les inicials de Network Emulation. Netem proporciona funcionalitats per emular el funcionament de les xarxes WAN. La versió actual suporta la simulació de retards (delays que afecten a la latència, perdues (loss), duplicació de paquets i reordenament de paquets.

A partir del nucli Linux 2.6 es pot activar netem (normalment està activat per defecte) activant:

Networking -->
  Networking Options -->
    QoS and/or fair queuing -->
       Network emulator

La comanda tc (part del paquet iproute2 que sol estar instal·lat per defecte) és l'encarregada de gestionar netem. Les llibreries i els fitxers de dades es troben a:

/usr/lib/tc

Recursos:

Exemples
Emular retards a la xarxa (delays, alta latència)
$ sudo tc qdisc add dev eth0 root netem delay 100ms

TODO: Now a simple ping test to host on the local network should show an increase of 100 milliseconds. The delay is limited by the clock resolution of the kernel (HZ). On most 2.4 systems, the system clock runs at 100hz which allows delays in increments of 10ms. On 2.6, the value is a configuration parameter from 1000 to 100 hz.

Es pot simular jitter amb:

$ sudo tc qdisc change dev eth0 root netem delay 100ms 10ms

IMPORTANT: Observeu l'ús de change! només es correcte si prèviament hem fet un add

El retard serà ara:

100ms ± 10ms. 

Cal tenir en compte que no és purament aleatori. Es pot millorar amb:

$ tc qdisc change dev eth0 root netem delay 100ms 10ms 25%

TODO: This causes the added delay to be 100ms ± 10ms with the next random element depending 25% on the last one. This isn't true statistical correlation, but an approximation.

Es poden també simular certes distribucions del delay:

$ sudo tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal

TODO: The actual tables (normal, pareto, paretonormal) are generated as part of the iproute2 compilation and placed in /usr/lib/tc; so it is possible with some effort to make your own distribution based on experimental data.

Simulació de pèrdua de paquets

Es pot simular una pèrdua aleatòria de paquets:

$ sudo tc qdisc change dev eth0 root netem loss 0.1%

Això provoca que un de cada 100 paquets es perdi. També es pot afegir una correlació:

# tc qdisc change dev eth0 root netem loss 0.3% 25%

IMPORTANT: When loss is used locally (not on a bridge or router), the loss is reported to the upper level protocols. This may cause TCP to resend and behave as if there was no loss. When testing protocol reponse to loss it is best to use a netem on a bridge or router

Duplicació de paquets

S'especifica de la mateixa forma que la pèrdua de paquets:

$ sudo tc qdisc change dev eth0 root netem duplicate 1%
Corrupció de paquets

Random noise can be emulated (in 2.6.16 or later) with the corrupt option. This introduces a single bit error at a random offset in the packet.

# tc qdisc change dev eth0 root netem corrupt 0.1% 
Reordenament de paquets

There are two different ways to specify reordering. The first method gap uses a fixed sequence and reorders every Nth packet. A simple usage of this is:

$ sudo tc qdisc change dev eth0 root netem gap 5 delay 10ms

This causes every 5th (10th, 15th, ...) packet to go to be sent immediately and every other packet to be delayed by 10ms. This is predictable and useful for base protocol testing like reassembly.

The second form reorder of re-ordering is more like real life. It causes a certain percentage of the packets to get mis-ordered.

$ sudo tc qdisc change dev eth0 root netem delay 10ms reorder 25% 50%

In this example, 25% of packets (with a correlation of 50%) will get sent immediately, others will be delayed by 10ms.

Newer versions of netem will also re-order packets if the random delay values are out of order. The following will cause some reordering:

# tc qdisc change dev eth0 root netem delay 100ms 75ms

If the first packet gets a random delay of 100ms (100ms base - 0ms jitter) and the second packet is sent 1ms later and gets a delay of 50ms (100ms base - 50ms jitter); the second packet will be sent first. This is because the queue discipline tfifo inside netem, keeps packets in order by time to send.


IMPORTANT: Mixing forms of reordering may lead to unexpected results Any method of reordering to work, some delay is necessary. If the delay is less than the inter-packet arrival time then no reordering will be seen.

ethtool

$ ethtool -g eth0 

Vegeu també

Recursos