Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli

Software Defined Networking (Dispensa del corso), Dispense di Telecomunicazioni

I principi di Internet, la network disaggregation, la ricerca esatta e prefix-match, la packet classification, lo switching e il buffer management. Vengono inoltre elencati gli obiettivi secondari dei fondatori di Internet e le generazioni di switch con network disaggregation. Il testo è utile per gli studenti universitari che studiano reti di calcolatori e software defined networking.

Tipologia: Dispense

2021/2022

In vendita dal 11/10/2022

MattBlue00
MattBlue00 🇮🇹

7 documenti

1 / 36

Toggle sidebar

Anteprima parziale del testo

Scarica Software Defined Networking (Dispensa del corso) e più Dispense in PDF di Telecomunicazioni solo su Docsity! S O F T WA R E D E F I N E D N E T W O R K I N G C O N C E T T I E S S E N Z I A L I 1. PRINCIPI DI INTERNET .................................................................................4 1.1 LAYERED DESIGN ...............................................................................................4 1.2 END-TO-END ARGUMENT ..................................................................................4 1.3 FILOSOFIA DI INTERNET .....................................................................................4 2. NETWORK DISAGGREGATION ....................................................................6 2.1 NETWORK DISAGGREGATION ..........................................................................6 2.2 PRIMA GENERAZIONE: OPENFLOW ..................................................................6 2.2 SECONDA GENERAZIONE: SWITCH OS ............................................................7 3. RICERCA ESATTA .........................................................................................8 3.1 RICERCA ESATTA ................................................................................................8 3.2 SOLUZIONI PER LA RICERCA ESATTA .................................................................8 3.3 FUNZIONI HASH ...............................................................................................9 3.4 HASH TABLE .......................................................................................................9 3.5 ALTRE SOLUZIONI PER LA RICERCA ESATTA .....................................................10 4. RICERCA PREFIX-MATCH ............................................................................11 4.1 CRITICITÀ DEL PROBLEMA DELLA RICERCA .......................................................11 4.2 RICERCA PREFIX-MATCH: TCAM ........................................................................11 4.3 RICERCA PREFIX-MATCH: TRIES ........................................................................12 4.4 RICERCA BINARIA SULLE LUNGHEZZE DEI PREFISSI .........................................13 5. PACKET CLASSIFICATION ...........................................................................15 5.1 PACKET CLASSIFICATION .................................................................................15 5.2 FLOW LABEL (IPv6) ...........................................................................................15 5.3 ALGORITMI PER LA CLASSIFICAZIONE .............................................................16 6. SWITCHING ..............................................................................................17 6.1 SWITCH: GENERALITÀ ......................................................................................17 6.2 ALCUNE TIPOLOGIE DI SWITCH .......................................................................17 6.3 CROSSBAR SWITCH .........................................................................................18 7. BUFFER MANAGEMENT .............................................................................20 7.1 CONGESTION CONTROL .................................................................................20 7.2 ACTIVE QUEUE MANAGEMENT .......................................................................21 7.3 SCHEDULING ...................................................................................................22 2 3. uso efficiente delle risorse. La limitazione, invece, è che tale struttura è un modello best-effort, dunque la gestione delle risorse è difficile. Gli sviluppatori di Internet avevano in mente anche altri obiettivi secondari, di seguito elencati in ordine di importanza decrescente: 1. robustezza ai guasti. I nodi e i collegamenti si guastano, ma le reti devono continuare a lavorare; occorre dunque preservare lo stato delle conversazioni attive. Le possibili soluzioni sono la replicazione (conservare lo stato in molteplici nodi) o il fate sharing (cioè, è accettabile perdere lo stato associato a un’entità fuori servizio). Quest’ultima soluzione è più robusta anche con scenari di guasto complessi ed è più facile da ingegnerizzare. Inoltre, tale soluzione prevede che i nodi abbiano solo soft-state. 2. servizi eterogenei e reti eterogenee. Infatti, Internet è una rete multiservizio, con molte applicazioni e diversi requisiti di qualità del servizio, in merito a affidabilità, consegna ordinata e latenza. Conseguentemente, è difficile modificare il collo della clessidra, ed è difficile esporre alle applicazioni le funzionalità dei livelli inferiori. 3. gestione distribuita. 4. efficienza economica. 5. semplicità di interconnessione. 6. accountability. Se l’ordine fosse diverso, Internet sarebbe profondamente diversa. Si notino le grandi assenti dagli obiettivi secondari dei fondatori: sicurezza, affidabilità, mobilità, supporto per connessioni intermittenti e automazione della gestione. 5 2 . N E T W O R K D I S A G G R E G AT I O N 2 .1 N E T W O R K D I S A G G R E G AT I O N Con network disaggregation si intende la scomposizione di uno switch o di un router nei suoi componenti hardware e software, che possono essere sviluppati e acquistati separatamente. Ciò ha l’obiettivo di ridurre i costi e di permettere di innovare e sviluppare indipendentemente i vari componenti. 2 . 2 P R I M A G E N E R A Z I O N E : O P E N F L O W La prima generazione di switch con network disaggregation ha ottenuto la programmabilità del piano di controllo. Il piano dati segue l’astrazione flow table: • le regole di match vengono eseguite sui campi dei pacchetti. • le azioni (inoltra, modifica, scarta, …) vengono eseguite da una lista. Un Openflow switch inoltra i pacchetti molto velocemente leggendo da una o più tabelle, e fornisce una API e un proto- collo per aggiungere o togliere righe dalle tabelle. Il Controller Openflow conserva informazioni di stato della rete, come la mappa, il carico e i flussi attivi. È logicamente centralizzato ed è implementato come un sistema distribuito per garantire scalabilità e resistenza ai guasti. Le applicazioni Openflow forniscono le funzioni del piano di controllo (routing, gestione dei guasti, …), e possono essere sviluppate indipendentemente dal controllore grazie alla API aperta. 6 La prima generazione di questo tipo di switch soffre essenzialmente di due problemi: • scalabilità non buona. • innovazione lenta. Tuttavia, gli switch virtuali ebbero molto successo. 2 . 2 S E C O N DA G E N E R A Z I O N E : S W I T C H O S La seconda generazione di switch con network disaggregation ha ottenuto la programma- bilità anche del piano dati. Gli switch/router diventano più simili a un server: infatti, hanno una CPU general purpose (x86/ARM) con Linux per la gestione di tutto ciò che non è reti, e hanno un packet-forwarding accelerator (“Network Processing Unit”) con driver per le funzioni di comunicazione (x86 per sistemi di fascia medio-bassa, FPGA o componenti specializzati per i sistemi di fascia alta). La Network Processing Unit può essere programmata in vari modi. La Portable Switch Architecture (PSA) usa un modello basato su parser programmabile, pipeline con match- action tablet (come Openflow) e deparser. Parser e pipeline possono essere programmate usando il linguaggio P4 (“Programming Protocol-Independent Packet Processors”). 7 3 . 5 A LT R E S O L U Z I O N I P E R L A R I C E R C A E S AT TA Un Ethernet bridge è un ripetitore filtrante con capacità di apprendimento. In particolare: • analizzando gli indirizzi sorgente, il bridge riempie una tabella di mappatura. • analizzando gli indirizzi destinazione e la tabella di mappatura, il bridge decide se inoltrare o scartare il pacchetto. Un nuovo pacchetto di 64 byte arriva ogni 51,2 ; dunque, per evitare la formazione di code, il bridge deve fare due ricerche (per la sorgente e per la destinazione) ogni 51,2 . Con due sole porte, si ha bisogno di effettuare una ricerca ogni 12,8 . Il primo bridge utilizzava una DRAM economica con tempi di accesso di 100 . Inoltre, la tabella doveva contenere 8000 righe. Dato che la ricerca binaria fornisce tempi di ricerca deterministici, implementare in hardware tale ricerca ha spostato il collo di bottiglia all’accesso in memoria. La ricerca binaria in una tabella di 8000 righe richiede accessi in memoria, dunque il tempo di ricerca finale è di 1,3 . I Gigaswitch usano tabelle hash per ridurre gli accessi in memoria. Nel caso medio, il tempo di accesso è costante, ma nel caso pessimo il tempo è lineare (il che non è affatto desiderabile!). Il segreto è utilizzare un hash “perfetto”: se si conosce l’insieme di chiavi e il fattore di carico è inferiore (o al più uguale) a 1, si può costruire una funzione di hash con probabilità di collisione nulla. Con tali funzioni, il caso pessimo ha tempo di ricerca costante. Il problema è che non si conoscono in anticipo le chiavi. I Gigaswitch usano una funzione di hash parametrica e un albero binario bilanciato di profondità massima pari a 3 per disambiguare una collisione. Ogni ricerca richiede al massimo 4 accessi in memoria. Nel caso che ci siano più di 7 elementi in un bucket, la chiave sovrabbondante viene salvata in una CAM, che viene ispezionata in parallelo. Se il numero di elementi nella CAM è troppo grande, i parametri hash vengono cambiati e la tabella viene risottoposta al processo di hashing. Si noti però che tale processo accade raramente, in quanto la tabella cambia piuttosto lentamente. μs μs μs ns ⌈log2 8000⌉ = 13 μs 10 4 . R I C E R C A P R E F I X - M AT C H 4 .1 C R I T I C I TÀ D E L P R O B L E M A D E L L A R I C E R C A Il problema della ricerca richiede di effettuare diverse osservazioni: 1. è poco probabile che due pacchetti successivi abbiano la stessa destinazione, dunque fare caching è inutile. 2. i pacchetti tendenzialmente sono piccoli (moltissimi sono TCP-ACK). 3. il collo di bottiglia della ricerca è l’accesso in memoria. 4. la lunghezza dei prefissi varia da 8 a 32 bit. 5. molti prefissi sono multicast o verso determinati host. 6. le tabelle di routing (in particolar modo se di grandi dimensioni) sono poco stabili. 7. per lavorare a velocità elevate, servono le costose SRAM. 8. IPv6 è in forte espansione, dunque le ricerche a 32 bit sono sempre più cruciali. 4 . 2 R I C E R C A P R E F I X - M AT C H : T C A M Una stringa binaria viene detta ternaria se contiene “0”, “1” e “?”, dove “?” è una wildcard di un bit. Per semplificare la notazione, si userà “*” come una wildcard per un qualsiasi numero di “?” consecutivi. Una Ternary Content Addressable Memory (TCAM) è una memoria che contiene stringhe ternarie di una data lunghezza. Quando riceve un input, la TCAM esegue la ricerca in parallelo su tutte le stringhe che possiede e restituisce la stringa più lunga che combacia con la chiave (le stringhe sono ordinate dalla più specifica alla meno specifica). Le TCAM sono estremamente veloci, ma sono grandi (10/12 transistor per bit), consumano molta energia (per via della comparazione parallela) e sono costose. Tuttora, non è chiaro cosa sia meglio per un router con milioni di prefissi. Nelle TCAM è necessario che i prefissi più lunghi vengano prima di quelli più corti. Dunque, aggiungere una stringa diviene un problema da considerare. Una soluzione naïf, supponendo che il prefisso da inserire abbia lunghezza i, è quella di spostare tutti i prefissi più lunghi, creare un buco all’inizio dei prefissi di lunghezza i e inserire il nuovo prefisso. Questa soluzione, tuttavia, è troppo lenta. Una soluzione migliore è quella di spostare i prefissi di lunghezza i+1 ricorsivamente, creare uno spazio all’inizio dei prefissi di lunghezza i e scrivere il nuovo prefisso. Questa soluzione richiede al massimo 32-i accessi in memoria per aggiornare la tabella; inoltre, piazzare degli spazi liberi nel mezzo della tabella dimezza gli accessi. 11 4 . 3 R I C E R C A P R E F I X - M AT C H : T R I E S L’unibit trie è un albero in cui ogni nodo contiene il next hop e un array con un “puntatore 0” e un “puntatore 1”. A ogni livello dell’albero, tutti i prefissi che cominciano con 0 si trovano nel sotto-trie puntato dal puntatore 0, mentre tutti i prefissi che cominciano con 1 si trovano nel sotto-trie puntato dal puntatore 1. Ogni sotto-trie è costruito ricorsivamente. Si notino i seguenti casi particolari: • un prefisso è sottoprefisso di un altro prefisso (nell’esempio, si considerino P4 e P2). Il prefisso più corto è contenuto dentro un nodo lungo il cammino. • alcuni sottoalberi hanno solo un ramo (nell’esempio, si consideri P3). Non ci sono rami per i bit rimanenti, perché sarebbe uno spreco di spazio e tempo. La ricerca per il match più lungo di un dato indirizzo comincia a partire dalla radice dell’albero, e continua finché non si incontra un puntatore vuoto o una stringa che non combacia. L’algoritmo tiene traccia dell’ultimo prefisso incontrato lungo il cammino, dunque, quando la ricerca fallisce, tale prefisso è il longest match. Gli unibit tries richiedono molti accessi in memoria (nel caso peggiore, 32). I multibit tries riducono gli accessi in memoria cercando in “passi” di n bit. Se n è fisso per l’intero trie, si parla di passo fisso, altrimenti si parla di passo variabile. Si noti che se il prefisso non è un multiplo del 12 5 . PA C K E T C L A S S I F I C AT I O N 5 .1 PA C K E T C L A S S I F I C AT I O N I middleboxes e i router differenziano i servizi controllando gli header dei protocolli dei livelli successivi (switching di livello 4 o persino di livello 7). Esempi di servizi sono i firewall, la gestione delle risorse, i servizi di priorità e il QoS routing. I router possono anche avere migliaia di regole del genere. I pacchetti vengono classificati grazie a un insieme di regole. Più regole possono fare match con un pacchetto, dunque è necessario che le regole abbiano una priorità. Il problema diventa trovare la regola di match con più alta priorità per ogni pacchetto. Ogni regola analizza diversi campi header in ogni messaggio. Si ricordi che: • ogni campo di un pacchetto è una stringa di bit di lunghezza fissata. • la posizione dei campi potrebbe dipendere dai valori presenti negli altri campi. • i match possibili sono esatti, di prefisso o di range. Ogni regola specifica una combinazione di K valori, uno per ogni campo. Si noti che alcuni valori possono essere una wildcard. Inoltre, ogni regola ha una priorità ed è associata a una direttiva, che specifica cosa fare col pacchetto (inoltro, scarto, …). Affinché i pacchetti vengano classificati, è necessario che: • la ricerca venga eseguita wire speed con pacchetti di dimensione minima. • le strutture dati siano piccole. • l’inserimento e la cancellazione siano infrequenti, cosicché la velocità di aggiornamento non sia un problema. Si noti che, nella classificazione stateful, le regole sono aggiunte e tolte dinamicamente in base a determinati eventi, e in tal caso la velocità di inserimento/cancellazione non è trascurabile. Una soluzione semplice è la ricerca lineare, ma è lenta per grandi database. Il caching, inoltre, non è una buona idea, perché l’evidenza sperimentale è che l’hit rate del caching è pari al 80%-90% (che è basso!). L’utilizzo di etichette (aggiunte in una classificazione precedente) richiederebbe cambiamenti al protocollo, mentre algoritmi di demultiplazione (cioè alberi/grafi decisionali) sono ottimi per testare una singola regola, ma la composabilità, ovvero la capacità di un algoritmo di implementare una ricerca su più regole senza avere costo lineare, è pessima. Le TCAM, d’altro canto, hanno chiavi molto lunghe se i campi dei pacchetti sono molteplici, occupano molto spazio, consumano molta energia elettrica, hanno un costo elevato e non supportano il range match (sarebbe necessario moltiplicare le regole). 5 . 2 F L O W L A B E L ( I P V 6 ) Il protocollo IPv6 prevede un’etichetta di 20 bit, detta flow label, il cui uso è opzionale. Tale etichetta viene assegnata dalla sorgente per identificare tutti i pacchetti dello stesso flusso. 15 Ai fini della classificazione dei pacchetti, il router fa caching della mappatura tra l’identificativo della sorgente e l’identificativo del flusso, e le regole di matching. Se la sorgente è fidata, ovverosia non cambia gli header, la classificazione è veloce. 5 . 3 A L G O R I T M I P E R L A C L A S S I F I C A Z I O N E Esistono molteplici algoritmi per la classificazione dei pacchetti, basati su tries gerarchici, alberi decisionali, metodi geometrici, cross producting e bit vector linear search. In generale, la classificazione richiede o molta memoria o molto tempo. L’idea dietro la bit vector linear search è che si faccia matching un campo alla volta, che si calcoli l’intersezione e che la si cerchi nei vari pacchetti. Per ogni campo, il match ritorna una stringa di bit, formata da tanti bit quante sono le regole. L’i-esimo bit è 1 se il pacchetto corrente fa matching con la i-esima regola per quel specifico campo. L’intersezione viene ottenuta con un AND logico su tutte le stringhe. La regola che matcha è quella che corrisponde alla posizione del primo 1 della stringa risultante. La complessità temporale dell’AND logico è lineare rispetto al numero di colonne della tabella delle regole, ma è molto inferiore della ricerca lineare semplice perché il numero di accessi in memoria è più piccolo. In particolare: • la complessità temporale è per i match individuali, mentre per calcolare l’intersezione. • la complessità spaziale è per i match individuali, mentre per i bit da salvare nel caso peggiore. Si tenga presente che gli aggiornamenti sono lenti, dato che il database deve essere ricostruito, ma l’algoritmo è comunque buono se l’insieme di regole ha dimensioni moderate. N O(K ) K O (N(K + 1)) O(K ) K O (N2K) 16 6 . S W I T C H I N G 6 .1 S W I T C H : G E N E R A L I TÀ Il cuore di un router, o più in generale di uno switch, è il componente che muove i pacchetti dal cavo di input al cavo di output. Lo switch deve decidere quali cavi di input e output debbano essere collegati, per ogni pacchetto (tra un pacchetto e il successivo passano solo pochi nanosecondi!). Inoltre, deve processare allo stesso tempo quante più coppie di cavi gli è possibile, anche in multicast. Matematicamente, questo è un problema di match bipartito: uno switch deve collegare tanti più cavi di input tanti quanti sono i cavi di output a loro associati, in soli 8 nanosecondi (il che significa che la velocità di uno switch deve essere di 40 Gbit/s!). Per ottenere un risultato del genere, si ricorre alle seguenti strategie: • sacrificare la precisione per risparmiare tempo. • sfruttare il parallelismo hardware. • randomizzazione. • utilizzare un sistema a priorità. 6 . 2 A L C U N E T I P O L O G I E D I S W I T C H Negli switch a memoria condivisa, i pacchetti vengono scritti nella memoria dello switch non appena vi arrivano, e vengono letti dalla stessa memoria non appena dei cavi di output divengono disponibili. Il collo di bottiglia è quindi la larghezza di banda della memoria: ad esempio, con 32 input e porte di output da 1 Gbit/s, la larghezza di banda della memoria deve essere di almeno 64 Gbit/s. Risultati del genere sono ottenibili unicamente con poche porte e con cavi lenti. Negli switch a CPU condivisa, i pacchetti vengono copiati, uno alla volta, dalla line card di input alla CPU e dalla CPU al line card di output, senza passare per la memoria. Ogni cosa passa attraverso la CPU grazie a un’architettura a bus (la quale viene attraversata due volte dal payload del pacchetto); tuttavia, la CPU ha già diverse mansioni da svolgere, e rappresenta dunque il collo di bottiglia di questa soluzione. Negli switch a singola CPU per line card, solo l’header del pacchetto attraversa la routing CPU, mentre il payload va dalla line card di input direttamente nella line card di output. Il pacchetto attraversa il bus sono una volta, e il bus è il collo di bottiglia di questa soluzione. 17 7. B U F F E R M A N A G E M E N T 7.1 C O N G E S T I O N C O N T R O L Quando il cavo di uscita è congestionato, i pacchetti vengono piazzati in una coda. A quel punto, ci sono due possibili scelte: • decidere se accettare il pacchetto in coda o meno (drop policy). • decidere qual è il prossimo pacchetto nella coda ad essere trasmesso (scheduling policy). La soluzione più semplice è la politica First-In First-Out (FIFO) con tail drop: tutti i pacchetti vengono accettati finché la coda non è piena, e i pacchetti meno recenti vengono trasmessi per primi. Tuttavia, questa soluzione non è affatto ottimale: infatti, il traffico Internet è dominato da TCP, e lo scarto di pacchetti TCP viene recepito dalle sorgenti come una dichiarazione implicita di congestione, e dunque rallentano. Con la politica di controllo congestione TCP Tahoe, quando un pacchetto viene perso, la velocità di trasmissione va a zero. Invece, con la politica Reno viene aggiunto il Fast Retransmit e il Fast Recovery. Quando nessun pacchetto viene scartato, la finestra di congestione si ingrandisce esponenzialmente, e poi linearmente (come con Tahoe). Se un singolo pacchetto viene scartato (ce ne si può accorgere grazie agli ACK mancanti), il gap viene ricolmato ritrasmettendo il pacchetto mancante, dividendo la finestra e continuando a ingrandirla linearmente. Se, invece, più pacchetti vengono scartati, il timeout finirà per scadere (si tratta di centinaia di millisecondi), e la finestra ritorna di dimensione 1. TCP proverà sempre a saturare la larghezza di banda e a perdere pacchetti: questo è un effetto desiderabile del comportamento esplorativo di TCP. Se le perdite sono isolate, le variazioni di velocità sono piccole. Le politiche per il controllo della congestione si evolvono ancora oggi: gli algoritmo più recenti (TCP cubic, TCP BBR) hanno un comportamento più aggressivo durante le fasi esplorative. La velocità cresce più in fretta (il che è positivo per reti ad alta velocità e alti ritardi), ma potrebbe causare perdite ingenti (perdita di fairness). Alternativamente, esiste la possibilità di notificare esplicitamente la congestione: il router può marcare il pacchetto invece di scartarlo, usando due bit nell’header IP e due bit nell’header TCP, se il router implementa un algoritmo di marcatura (AQM - Active Queue Management). 2 0 La gestione della congestione con FIFO e tail drop non è affatto una buona idea. Altri motivi che supportano questa affermazione sono: • grandi quantità di pacchetti scartati, inviati dalla stessa sorgente, causano la scadenza del timeout di ritrasmissione. • l’indicazione di congestione è notificata a tutte le sorgenti contemporaneamente, dunque tutte le sorgenti rallentano contemporaneamente (il che è inefficiente), aumentano la loro velocità contemporaneamente (causando congestione) e sincronizzano il loro ciclo di controllo congestione (sprecando molta della larghezza di banda disponibile). • le sorgenti più avide dominano quelle meno avide. • si ottengono lunghe code e alti RTT senza un aumento in throughput (bufferbloat). Gli obiettivi per una migliore gestione dei buffer e per delle politiche di scheduling migliori sono: 1. miglior supporto per la gestione delle congestioni. I router dovrebbero fornire delle informazioni utili alle sorgenti TCP scegliendo quali pacchetti scartare e quali no. 2. condivisione equa dei collegamenti tra i flussi in competizione. I flussi avidi e aperti da molto non dovrebbero accaparrarsi tutti i buffer, lasciando i flussi restanti a bocca asciutta. 3. fornire Qualità del Servizio (QoS). Idealmente, è desiderabile fornire una larghezza di banda precisa e garanzie sui ritardi dei vari flussi, in base alle applicazioni. 4. evitare il bufferbloat. Si vuole un alto throughput e un basso RTT. 7. 2 A C T I V E Q U E U E M A N A G E M E N T Quando la lunghezza media delle code supera una data soglia, l’algoritmo Random Early Detection (RED) comincia a marcare randomicamente dei pacchetti (se vi è il supporto per l’Explicit Congestion Notification - ECN) o a scartarli (se tale supporto è assente), anche se c’è spazio nella coda. La probabilità di marcatura/scarto è una funzione della lunghezza media delle code. I vantaggi dell’algoritmo RED sono: • gli scarti sono isolati e attivano Fast Retransmit a poche sorgenti contemporaneamente, evitando sincronizzazione e mantenendo il throughput TCP complessivo alto. • in situazione di equilibrio, nel router collo di bottiglia, la dimensione della coda è circa attorno alla soglia. • usare la lunghezza media della coda permette alle raffiche di pacchetti di passare senza subire perdite. • la scelta ottimale dei parametri di sistema dipende dalla velocità dei collegamenti, dal ritardo di propagazione e dal RTT atteso delle connessioni. 21 L’algoritmo scarta a un ritmo . Per evitare che gli scarti siano troppo ravvicinati, tiene conto dello scarto precedente, e aggiorna come segue: dove è il numero di pacchetti inviati dopo l’ultimo scarto. Per evitare di mantenere troppi campioni ai fini del calcolo della lunghezza media delle code, RED utilizza una media pesata esponenzialmente: dove sampleLen è l’istantanea lunghezza della coda campionata in un dato momento, e un peso arbitrario. I tempi di campionamento dipendono dalla scelta tra: • implementazione software. Il campionamento viene effettuato ogni volta che arriva un pacchetto (il campionamento è veloce ma meno preciso, secondo il teorema PASTA - Poisson Arrivals See Time Averages). • implementazione hardware. Il campionamento viene effettuato a intervalli regolari. 7. 3 S C H E D U L I N G Per offrire Qualità del Servizio, il router dovrebbe fornire a ogni flusso delle garanzie sulla larghezza di banda (cioè quanti bit può servire in un dato intervallo di tempo) e sui limiti massimi di ritardo (cioè il tempo che intercorre tra l’arrivo del pacchetto e l’esecuzione del servizio associato). Si ha inoltre bisogno di molteplici code verso le uscite (una singola coda in uscita farebbe sì che i flussi più avidi monopolizzino il servizio, senza fairness, garanzie di larghezza di banda né di limiti di ritardo), e dunque di un classificatore che scelga la coda per ogni pacchetto, di uno schema di gestione dei buffer per ogni coda e di uno scheduler che scelga quale coda servire. Gli scheduler più comuni sono Strict Priority, Round Robin (RR) e le sue varianti (Deficit Round Robin - DRR, Class-Based Queuing - CBQ). Lo scheduler Round Robin (RR) mantiene una coda per ogni flusso e serve un singolo pacchetto per ogni coda, anche se risulterebbe ingiusto nel caso in cui i pacchetti avessero dimensione variabile. Idealmente, un Round Robin bit-by-bit potrebbe fornire garanzie riguardo alla larghezza di banda e ai limiti massimi di ritardo anche alle code con pacchetti di dimensione variabile. p p p = p 1 − cp c avgLen = (1 − w) ⋅ avgLen + w ⋅ sampleLen w 2 2 spostamento, mentre la soft IRQ è messa in coda quando lo spostamento è terminato. In questo modo, il gestore della hard IRQ può ritornare un risultato il più velocemente possibile. Inoltre, quando il carico è notevole, la hard IRQ può anticipare la soft IRQ, nel senso che, così facendo, i nuovi pacchetti vengono messi in coda, ma quelli più vecchi non vengono rimossi. Perciò, i pacchetti vengono scartati ma ritrasmessi. Questo fenomeno è detto receiver livelock. 4. il soft interrupt dà l’inizio al processamento del pacchetto a livello IP, verificando le regole di filtrazione del traffico (accetta o scarta) e controllando la destinazione (se è destinato a questo nodo, si invia agli strati superiori, altrimenti si invia in una coda di uscita o si scarta). 5. il processamento locale a livello IP controlla se il pacchetto è un frammento (in tal caso, lo sposta nel buffer dei frammenti) e trova il protocollo di trasporto (TCP, UDP, …). 6. il processamento a livello TCP trova la socket (se assente, si manda un RST), la ascolta e procede alla fase di handshake; poi, apre la socket e processa la coda TCP. 7. il processamento della coda TCP verifica i sequence numbers e processa gli ACKs. I dati vengono messi in ordine nella coda della socket in ricezione; se l’applicazione sta aspettando dei dati, viene risvegliata, mentre i dati danneggiati vengono piazzati in una coda dedicata. 8. i dati vengono spostati nello spazio utenti e le applicazioni vengono eseguite. 8 . 3 E N D N O D E S E PA C C H E T T I I N U S C I TA Quando un pacchetto esce da un endnode: 1. l’applicazione esegue una system call, copia i dati dallo spazio utenti al buffer della socket e verifica che ci sia un percorso possibile verso la destinazione (in caso non ci fosse, ritorna un errore). 2. viene costruito l’header TCP e viene controllata la finestra di trasmissione TCP. Se non c’è spazio nella finestra, il pacchetto viene messo in una coda ad attendere. 3. viene eseguito il processamento IP e vengono controllare le regole di filtraggio del traffico. 4. viene costruito l’header relativo al livello di collegamento e il pacchetto viene messo nella coda del dispositivo di rete. Se il dispositivo è impegnato, il pacchetto viene messo in attesa. 5. quando il dispositivo è pronto, il pacchetto viene copiato nel dispositivo. 6. il dispositivo trasmette il pacchetto e manda un interrupt. 7. quando l’interrupt giunge a destinazione, rimuove il pacchetto dalla coda e manda un nuovo pacchetto. 2 5 8 . 4 L O S VA N TA G G I O D E L L A M O D U L A R I TÀ Si consideri un server HTTP che serve pagine web statiche. Su richiesta, il server legge un file dal disco e lo manda su una connessione TCP. Lo stesso dato, tuttavia, viene copiato più volte dalla memoria: prima nella cache, poi nel server buffer nello spazio utenti, poi ancora nel socket buffer e infine nel dispositivo di rete. Le copie multiple (disco-cache, cache- applicazione, applicazione-kernel e kernel-scheda di rete, tenendo presente anche del calcolo del checksum TCP) consumano la larghezza di banda del bus e la memoria. Esistono tre possibili soluzioni: usare una memoria per la scheda di rete, la tecnica copy-on-write o il Remote Direct Memory Access. L’implementazione della memoria della scheda di rete è semplice se il sistema operativo usa un’architettura con memoria mappata, poiché parte della memoria del kernel potrebbe essere nella scheda, e i checksum IP e TCP potrebbero essere calcolati dalla stessa scheda che riceve i dati. Tuttavia, viene richiesta molta memoria nella scheda, e bisogna cambiare il processamento dei pacchetti per impedire che dati erronei o non riconosciuti siano spediti in un’applicazione. Alcuni sistemi operativi offrono copy-on-write (CoW), permettendo a un processo di replicare una pagina di memoria virtuale a un costo basso. La pagina copiata è un puntatore alla copia fisica della stessa pagina. Se una delle due pagine virtuali (l’originale o la copia) viene modificata, il sistema operativo genera una nuova copia fisica (ma ciò non dovrebbe avvenire di frequente). I problemi del CoW sono che non è disponibile in UNIX e in Windows, e che l’implementazione (ad esempio in Solaris) cambia la classica semantica dell’invio TCP/UDP (l’applicazione non può riutilizzare il buffer dopo aver spedito il pacchetto). La soluzione basata su Remote Direct Memory Access (RDMA) sposta i dati tra due memorie attraverso la rete, senza coinvolgere la CPU. I suoi problemi sono come la scheda di rete ricevente apprende dove piazzare i dati, e come mantenere la sicurezza e la protezione. Questa tecnica è diffusamente utilizzata negli Storage Area Networks (SAN): Fiber Channel e InfiniBand utilizzano protocolli proprietari, mentre ISCSI usa TCP/IP, il che implica la necessità che TCP sia implementato nella scheda di rete. Questa soluzione, inoltre, è utilizzata anche nei grandi data centers di Google e Azure. Le applicazioni inviano dati di rete attraverso il kernel del sistema operativo, il che richiede l’utilizzo di una system call, che il kernel copi i dati nel suo spazio e che il kernel processi i pacchetti e li copi nella memoria della scheda di rete. Durante la ricezione, il problema è analogo. Gli Application-Device Channels (ADC) permettono alle applicazioni di inviare/ ricevere dati direttamente verso/da la scheda di rete. Per proteggere i dati di ciascuna applicazione, il sistema operativo dà alla scheda di rete una lista di pagine valide per ogni 2 6 applicazione. Quando una data applicazione esegue una richiesta riguardo a una pagina, la scheda di rete deve controllare se tale pagina è nella lista di validità. Se l’insieme di pagine fosse salvato come una lista, la complessità della validazione sarebbe pari a , dove è il numero di pagine. Se invece l’insieme di pagine fosse salvato in un array, l’applicazione potrebbe fornire un indice per l’array e rendere il tutto più veloce. Si noti che la validazione consiste in un controllo dei limiti, in una ricerca e in una comparazione. O(n) n 2 7 Wireshark è un tool con interfaccia grafica simile a tcpdump. In aggiunta ai filtri BPF applicati quando un pacchetto viene ricevuto, Wireshark utilizza anche dei protocolli dissettori post-cattura. Infine, si noti che esiste una versione nuova della macchina BPF, detta Extended BPF (eBPF), che contiene dieci indirizzi aggiuntivi a 64 bit. 3 0 10 . M I S U R A Z I O N E D E L T R A F F I C O 10 .1 M I S U R A R E I L T R A F F I C O D E L L A R E T E Misurare il traffico della rete la rende più osservabile; l’ingegneria del traffico la rende più controllabile. Gli strumenti base per la misurazione del traffico sono la conta dei pacchetti e degli ottetti. Essi forniscono indicazioni utili per: • l’identificazione dei flussi di traffico più significativi, per una migliore pianificazione della portata dei collegamenti. • il rilevamento di possibili attacchi. • l’amministrazione e la contabilità. • la verifica dei Service Level Agreements (SLA). 10 . 2 M AT R I C E D E L T R A F F I C O Una matrice del traffico (traffic matrix - TM) fornisce, per ogni punto di ingresso nella rete e per ogni punto di uscita , il volume di traffico da a in un dato intervallo di tempo. La matrice del traffico non considera i percorsi interni, dunque - nell’esempio fornito - la traiettoria dei due flussi (uno continuo e l’altro tratteggiato) non è rilevante. La matrice del traffico, tuttavia, dipende dal momento in cui si effettua la rilevazione e dalle applicazioni coinvolte. Si può facilmente misurare il totale del traffico entrante in un dato nodo e il totale del traffico uscente da un altro nodo. Però, non è possibile misurare direttamente la quantità di traffico che da uno specifico nodo va verso un altro specifico nodo; occorre dunque stimarla. Si consideri una rete con cavi di ingresso/uscita. La matrice di traffico ha celle da riempire, poiché per tutte le celle sulla diagonale vale . Si hanno inoltre misurazioni di ingressi e misurazioni di uscite. Ad ora, si avrebbero equazioni e incognite, dunque il sistema non è ancora risolvibile. Si introduce quindi un’importante assunzione semplificativa, nota come gravity model, che asserisce che il traffico tra ogni coppia di collegamenti è proporzionale al traffico totale diretto verso quei nodi. Quindi: i j T(i, j) i j N N(N − 1) T(i, i) = 0 N N 2N N(N − 1) T(i, j) = Tin(i) Tout( j) ∑N k=1 Tout(k) 31 Si ribadisce che l’assunzione è estremamente semplificativa, dunque non molto precisa. Tuttavia, può essere rifinita aggiungendo informazioni sui veri percorsi di routing, sulle misurazioni effettuate internamente ai collegamenti e su altro ancora. 10 . 3 C O N TA R E I PA C C H E T T I : L A R G E S T C O U N T F I R S T Il passo fondamentale per la misurazione del traffico è la conta dei pacchetti e dei byte. A tale scopo, esistono molti contatori (milioni, per l’esattezza) di grande capacità (64 bit ciascuno), e più di uno di loro va aggiornato per ogni pacchetto; serve pertanto molta (costosa) memoria veloce. Affinché si possa risparmiare qualcosa sulla memoria (tenendo a mente che la località è scarsa, dunque non c’è vantaggio nel caching dei contatori utilizzati più recentemente), si deve mantenere una versione corta (16 bit) di tutti i contatori nella memoria veloce, mentre la versione lunga viene mantenuta in una memoria più lenta (ma a basso costo). Periodicamente, si sceglie un contatore dalla memoria veloce e si aggiunge il numero fino ad allora raggiunto al corrispondente contatore nella memoria lenta; dopodiché, si resetta il contatore piccolo. Per assicurare correttezza, ogni contatore deve essere svuotato dal contatore grande corrispettivo prima che ci sia un overflow. Ad ogni arrivo di un pacchetto, aggiorniamo un contatore nella memoria veloce. Se la memoria veloce è volte più veloce della memoria lenta, si può svuotare e resettare un contatore ogni pacchetti. Con l’algoritmo Largest Count First (LCF), il contatore nella memoria veloce che viene scelto per essere svuotato è quello che contiene il numero più grande. Si può dimostrare che con LCF non si ha overflow se, detto il numero totale di bit disponibili nella memoria veloce (SRAM) e il numero di contatori, vale: Tuttavia, implementare LCF può essere difficoltoso, poiché l’algoritmo ha bisogno di tempo e memoria. Per questa ragione, è possibile contare anche su una versione semplificata di LCF. Sia un array di contatori nella memoria veloce. Ogni pacchetti: • sia il -esimo contatore di il più grande aggiornato nell’ultimo ciclo di pacchetti. • se , allora si svuota e resetta il contatore -esimo; altrimenti, si svuota e resetta un qualsiasi altro contatore. Naturalmente, perché non ci sia overflow, si ha bisogno di un più grande, ma non eccessivamente. 10 . 4 C O N TA R E I PA C C H E T T I : R A N D O M I Z E D C O U N T I N G La tecnica del randomized counting rinuncia in accuratezza o in precisione per incrementare l’efficienza. Quando un pacchetto arriva, il contatore viene incrementato con probabilità: b b c N c ≈ log (log (b ⋅ N)) S b j S b S[ j] ≥ b j c 3 2 La varianza è grande, dunque possiamo fare la media delle stime ottenute con più funzioni hash diverse. Date funzioni hash, sia la quantità maggiore di “0” iniziali visto per la -esima funzione hash. La stima del numero di flussi distinti è: con Si noti, infine, che Flajolet ha sviluppato di recente un algoritmo ancora migliore, detto HyperLogLog. 10 . 7 C O N TA R E I PA C C H E T T I : H A S H - B A S E D S A M P L I N G Un’altra tecnica per contare i pacchetti è quella denominata Trajectory Sampling. Se il campionamento avviene indipendentemente a ogni router, non sarà possibile seguire il percorso di un pacchetto sulla rete. Alcuni router lo campionano, altri no, dunque se si prova a seguirlo, ci si perde. Si desiderano traiettorie semplici, e si desidera che un pacchetto venga campionato o da tutti i router o da nessuno. In questo modo, possiamo tracciare il percorso di un pacchetto in rete. Per forzare i router a prendere decisioni di campionamento coordinate, si estrae un digest da ogni pacchetto, estraendo una stringa di bit dai campi del pacchetto che non cambiano hop dopo hop (ad esempio, gli indirizzi IP e i payload vanno bene, mentre i TTL e gli indirizzi MAC no). Sia tale stringa , e si faccia hashing su di essa con la funzione , identica per tutti i router (hashing consistente). Sia , dunque il digest del pacchetto è un numero nel range . Si scelga poi una soglia . Se , il pacchetto viene contato. Assumendo che l’output di sia una variabile aleatoria uniformemente distribuita, un dato pacchetto è contato in tutti i router con probabilità . Si può salvare il pacchetto campionato o solo il digest, ma se si salva il digest si ha bisogno di una funzione di hash distinta . 10 . 8 F I L T R I D I B L O O M Si supponga di aver trovato un pacchetto malevolo con un indirizzo IP sorgente falsato e di voler risalire alla sua sottorete di origine. Tale operazione, denominata IP traceback, risulta utile per difendersi da un singolo aggressore che sfrutta attacchi di tipo DoS asimmetrici, ed è ancora un mattone fondamentale per le indagini forensi o per risposte agli attacchi più sofisticate. Tuttavia, filtrare semplicemente questi indirizzi causerebbe due side effects: • scartare i pacchetti provenienti dalle reti che non sono downstream (fattibile solo ai margini della rete). m xi i w = 2A ϕ A = 1 m m ∑ i=1 xi m h(m) h : {0,1}* → [0,R) 0 ≤ h(m) < R B < R h(m) < B h(m) B R g(m) 3 5 • scartare i pacchetti provenienti dalle reti che non sono nel reverse path (richiederebbe routing simmetrico). Risalire alla sorgente non è un atto irrilevante, perché - prima di essere catturato - il pacchetto ha viaggiato per tutta la rete. Risalire alla sorgente di un pacchetto malevolo pone delle sfide: 1. la ricostruzione del percorso del pacchetto è difficile, perché il pacchetto potrebbe essere stato trasformato nel suo percorso lungo la rete. 2. mantenere integralmente il pacchetto è problematico, perché - specialmente ad alte velocità - i requisiti di memoria sono proibitivi. 3. salvare i log estesi dei pacchetti comporta un rischio per la privacy, attirando l’interesse di chi vuole spiare la rete. La soluzione a queste problematiche è l’utilizzo di un filtro di Bloom da resettare a ogni dato intervallo di tempo. I filtri di Bloom forniscono un algoritmo veloce per capire se un pacchetto appartiene a un dato insieme: • utilizzano un array di bit di dimensione fissa, pari a , dove è il numero di bit del digest. L’array viene inizializzato con zeri. • come indice per l’inserimento di un “1” nell’array, si usano hash a -bit. • si computano hash, ottenendo digest. Se , allora il pacchetto viene scartato. La probabilità di un falso positivo con il filtro di Bloom è pari a: dove è il numero di elementi presenti nel filtro. Si noti che il tasso di falsi positivi è minimo quando . m = 2b b n k d1, d2, . . . filtro[di] = 1 ∀i (1 − e− kn m ) k n k = m n log 2 3 6
Docsity logo


Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved