Le qdisc Classful sono molto utili se si dispone di diversi tipi di traffico, i quali dovrebbero essere trattati in maniera diversa.
Uno dei metodi classful è il così detto "cBq", "class base queue", che risulta essere il più famoso, ma solo percheè risulta essere il più antico e complesso.
Il flusso di dati nei metodi classful
Quando entra del traffico dati entra in un accodamento classful, deve essere selezionato ed inviato in qualche classe, il dato ha quindi bisogno di essere "classificato". Per sapere che cosa a che fare con un pacchetto, si ricorre ai "filtri". E' importante sapere che i filtri sono usati da una qdisc, e non il contrario!
I filtri connessi a tale qdisc ci forniscono una decisione e che la qdisc utilizza per accodarli in una classe. Ogni sottoclasse può a sua volta ricorrere ad altri filtri per ulteriori selezioni e classificazioni. In caso contrario, la classe accoda il pacchetto alla qdisc alla quale è connessa.
Queste qdisc classful inoltre possono eseguire uno shaping dei dati, che dopo essere stati classificati possono essere ritardati e inviati ad una velocità impostata. Come nei casi classless, avremo bisogno di questa soluzione, nei casi in cui si dispone di una interfaccia ad alta velocità (ad esempio, Ethernet) connessa un dispositivo più lento (un modem via cavo).
La gerarchia nelle qdisc: roots, handles, siblings e parents
Ogni interfaccia ha in uscita una "root qdisc" (root = radice). Di default è un tipo di accodamento pfifo_fast, che non una le classi. Per ogni qdisc o classe è assegnato un handle (identificativo), che può essere usato per riferirsi a quella particolare coda o classe nel resto della configurazione. Oltre ad una qdisc in uscita una interfaccia può averne una in ingresso, che ne regola il traffico (policing).
Gli handles di queste qdiscs sono composti da due parti separate dal simbolo ":" e queste sono: :.
Solitamente la root qdisc è '1:', che vuol dire '1:0'. Il numenro minore di una qdisc è sempre 0.
Le classi necessitano d'avere lo stesso numero maggiore come loro genitore. Questo numero deve essere unico per una configurazione d'ingresso o una d' uscita. Il numero minore deve essere unico per una qdisc e le sue classi.
Vediamo di ricapitolare la situazione forse un po confusa facendo un esempio:
1: root qdisc
|
1:1 child class
/ | \
/ | \
/ | \
/ | \
1:10 1:11 1:12 child classes
| | |
| 11: | leaf class
| |
10: 12: qdisc
/ \ / \
10:1 10:2 12:1 12:2 leaf classes
Come detto prima i nodi di questo albero che non hanno il numero minore (è sottinteso ":0") sono delle qdisc, mentre gli altri sono classi.
Tutte le classi terminano con una qdisc, dove non appare esplicitamente questo è sottinteso e la qdisc sarà una semplice fifo. Il primo numero ("maggiore") di un handle di classe rappresenta "a cosa" la classe è collegata, questo significa che una classe 10:2 sarà collegata alla coda 10: o 10:0.
Ad ogni nodo è collegato un filtro attraverso il quale si seleziona e si smista il traffico negli altri nodi.
Un pacchetto ad esempio può, attraverso una serie di filtri in ogni nodo, fluire nella catena:
ed andare a finire nella qdisc collegata alla classe 12:2.
Comunque è anche possibile che un filtro applicato alla root mandi il pacchetto direttamente nella classe desiderata 12:2:
Come i pacchetti vengono fatti uscire dall'accodamento (dequeued).
Quando il kernel ha bisogno di inviare i pacchetti accodati all'interfaccia di destinazione si rivolge alla root qdisc "1:" facendo una richiesta di "dequeue", questa è passata alla 1:1, che a sua volta è passata alla 10:, 11: e 12:, ognuna fa la richiesta alle suoi discendenti. In questo caso il kernel ha bisogno di ripercorrere tutto l' "albero" perché solo il nodo 12:2 contine il pacchetto.
In poche parole, le classi "figlie" possono parlare solo con i loro genitori e mai con una interfaccia, e quindi solo la qdisc radice può ricevere ordini dal kernel e disaccodare un pacchetto.
L'esito di questo sistema è che le classi figlie non possono mai disaccodare i pacchetti più velocemente delle classi da cui discendono. Questo in effetti è quello che si vuole ottenere, infatti , se avessimo una SFQ come qdisc genitore, la quale non fa shaping, ma solo scheduling, e una TBF, in grado di ritardare i pacchetti come figlia, allora ci troveremo in una situazione ottimale, dato che la TBF discaccoderebbe i pacchetti più lentamente, ad una velocità impostata da noi e la SFQ penserebbe a miscelarli con l'altro traffico restante. Se ci trovassimo nella situazione contraria tutto il lavoro di scheduling della SFQ sarebbe in parte vanificato dal rallentamento a monte nella TBF, che potrebbe non essere quello che vogliamo.





