Modulo QSPN - Routing di pacchetti verso indirizzi IP interni

Con gli esempi riportati in questo documento:

Indirizzi IP interni ad un g-nodo

Abbiamo detto che l'uso di indirizzi IP interni è un accorgimento che mitiga molto il disagio dovuto al cambio di indirizzo di un intero g-nodo di grandi dimensioni.

Esempio 1.1

Consideriamo questa porzione di una rete:

grafo1.adraw

Nella rete G usiamo una topologia di 3 livelli con gsize=4. Quindi abbiamo 43=64 indirizzi, che traduciamo in indirizzi IP dal 10.0.0.0 al 10.0.0.63.

Abbiamo assegnato ai nodi questi indirizzi:

Le tabelle di routing dei vari nodi sono semplici da dedurre. Ad esempio, se a vuole raggiungere f sa che per 10.0.0.8/30 deve usare come gateway b. Poi b sa che per 10.0.0.8/30 deve usare come gateway e. Poi e sa che per 10.0.0.11/32 deve usare come gateway f. La destinazione è raggiunta.

Supponiamo ora che il g-nodo g2 cambi indirizzo e da [2, 0] diventi [1, 1]. Ovviamente le comunicazioni in corso tra a e f saranno da ripristinare poiché l'indirizzo di f è divenuto 10.0.0.23.

Vediamo però cosa succede ad una comunicazione in corso tra d e f. Anche questa si perde, poiché entrambi i nodi cambiano il loro indirizzo.

Supponiamo invece di usare degli indirizzi IP interni ai g-nodi di livello 1. Questi g-nodi al loro interno hanno 4 posizioni valide. Diciamo che le traduciamo in indirizzi IP dal 10.0.1.0 al 10.0.1.3, i quali non interferiscono con il range di indirizzi visto prima.1

Quindi abbiamo che gli indirizzi assegnati ai nodi sono:

Le tabelle di routing dei vari nodi hanno di conseguenza maggiori informazioni. Ad esempio, se d vuole raggiungere f e usa il suo indirizzo interno al g-nodo di livello 1 sa che per 10.0.1.3/32 deve usare come gateway e. Poi e sa che per 10.0.1.3/32 deve usare come gateway f. La destinazione è raggiunta.

Se ora il g-nodo g2 cambia indirizzo e da [2, 0] diventa [1, 1], le comunicazioni in corso tra d e f rimarranno valide e funzionanti poiché l'indirizzo di f in g2 è rimasto 10.0.1.3.


Nota 1: Per una strategia efficiente di individuazione dei range di indirizzi IP interni ai g-nodi si veda il documento livelli e bits.

Problema dei nodi virtuali

I nodi virtuali sono previsti per evitare che una migrazione di un nodo provochi lo split (disconnessione) di un suo g-nodo superiore. La contromisura che evita lo split consiste nel fatto che un singolo nodo appartiene contemporaneamente a diversi g-nodi di livello 1. All'interno del g-nodo dal quale è uscito, il nodo assume un indirizzo virtuale al livello 0 e di connettività ai livelli da 1 a j, dove j è il livello del g-nodo più alto dal quale il nodo migrando è uscito.

Ma l'esistenza di nodi virtuali, cioè di singoli nodi che appartengono contemporaneamente a diversi g-nodi di livello 1, comporta un problema con il routing tramite indirizzi interni.

Consideriamo un nodo n che ha, oltre all'indirizzo definitivo, un indirizzo di connettività ai livelli da 1 a j. Questo significa che i suoi 2 indirizzi suddetti appartengono a 2 distinti g-nodi di livello 1, a 2 distinti g-nodi di livello 2, ... a 2 distinti g-nodi di livello j.

Se n riceve un pacchetto da inoltrare ad un indirizzo IP interno al g-nodo di livello 1, questo indirizzo IP da solo non contiene informazioni sufficienti a identificare la vera destinazione e quindi il percorso da seguire. Lo stesso accade se n riceve un pacchetto da inoltrare ad un indirizzo IP interno al g-nodo di livello 2. Fino al livello j.

Ovviamente la stessa cosa vale in generale per l'esistenza di g-nodi di connettività ai livelli da i a j (e virtuali al livello i - 1).

Illustriamo nel dettaglio il problema con un esempio che tratta il caso di uno o più nodi che adottano un indirizzo di connettività al livello 1. Cercheremo poi di esprimere la soluzione trovata in termini generici di nodi che adottano un indirizzo di connettività ai livelli da i a j.

Esempio 2.1

Consideriamo questa porzione di una rete:

grafo2.adraw

I nodi reali sono a, c, d, e, f. I link reali sono a-e, c-e, d-e, f-e. Per motivi riguardanti i vincoli di topologia (che non sono evidenti da questa porzione della rete) diciamo che a e c devono far parte dello stesso g-nodo g1, mentre il nodo e che prima ne faceva parte ha dovuto migrare in g2. Per evitare lo split, e è rimasto con un identificativo virtuale al livello 0 e di connettività al livello 1 dentro g1; il suo indirizzo in g1 è rappresentato nel disegno come ei(1).

Con gli stessi parametri di topologia visti nell'esempio 1.1, possiamo ipotizzare questi indirizzi per i nodi:

Il problema sorge quando si devono impostare le rotte nel nodo e.

Ad esempio, se a vuole raggiungere f sa che per 10.0.0.8/30 deve usare come gateway e. Si ricordi infatti che e e ei(1) sono lo stesso nodo. Poi e sa che per 10.0.0.11/32 deve usare come gateway f. La destinazione è raggiunta.

Ma se a vuole raggiungere c usando il suo indirizzo interno in g1, cioè 10.0.1.3? Deve usare come gateway e. Mentre se d vuole raggiungere f usando il suo indirizzo interno in g2, cioè 10.0.1.3? Deve usare come gateway e.

Quindi il nodo e dovrebbe avere 2 rotte diverse per raggiungere 10.0.1.3 a seconda se il pacchetto da inoltrargli è proveniente da a o da d.

Si noti che il problema non si pone se l'indirizzo IP a cui il nodo e deve inoltrare un pacchetto fosse uno interno nel g-nodo di livello 2. Infatti entrambi gli indirizzi di e ([5, 1, 0] e [1, 2, 0]) appartengono allo stesso g-nodo di livello 2 ([0]).

Sebbene appaia complessa, questa situazione può essere ancora gestita. Quando il nodo e riceve un pacchetto IP nel suo header vede l'indirizzo IP del mittente e quello di destinazione. Nel frame Ethernet in cui è incapsulato vede l'indirizzo MAC del nodo che lo ha trasmesso e quello della sua interfaccia che lo ha ricevuto. Quindi il nodo e può istruire le sue policy di routing così:

Ma si capisce che quando la migrazione ha interessato più di un singolo nodo la soluzione diventa inefficace. Lo vediamo nel seguente esempio.

Esempio 2.2

Consideriamo questa porzione di una rete:

grafo3.adraw

I nodi e ed r in questo caso migrando da g1 a g2 sono rimasti con un indirizzo virtuale al livello 0 e di connettività al livello 1 dentro g1.

Con gli stessi parametri di topologia visti nell'esempio 2.1, possiamo ipotizzare questi indirizzi per i nodi:

Se a vuole raggiungere c usando il suo indirizzo interno in g1, cioè 10.0.1.3, deve usare come gateway e. Poi e sa che per 10.0.1.3/32 quando il pacchetto proviene da a deve usare r.

A questo punto il nodo r riceve un pacchetto IP. Nel suo header vede l'indirizzo IP del mittente (10.0.1.1) e quello di destinazione (10.0.1.3). Nel frame Ethernet in cui è incapsulato vede l'indirizzo MAC del nodo che lo ha trasmesso (e) e quello della sua interfaccia che lo ha ricevuto. Il nodo r non sa in alcun modo se il pacchetto proveniva da a o da d, prima di passare per e.

Soluzione

La soluzione a questo problema appare evidente se si guarda il disegno del grafo. Bisogna fare in modo che il nodo virtuale ei(1) sia effettivamente distinto dal nodo e. E che il nodo virtuale ri(1) sia effettivamente distinto dal nodo r. E infine che l'arco virtuale ei(1)-ri(1) sia effettivamente distinto dall'arco e-r. Cioè che risultino avere un indirizzo MAC distinto.

Con maggiore precisione, quando un nodo 𝛼 migra da g ad h (g-nodi distinti di livello i il cui minimo comune g-nodo è di livello j + 1, con ji) si assegna nel vecchio g-nodo un indirizzo di connettività ai livelli da i a j. Consideriamo l'arco a che il nodo 𝛼 aveva in g con il vicino nodo 𝛽. In base al livello del massimo distinto g-nodo di 𝛽 per 𝛼, valore che chiamiamo 𝜀, possono esserci questi casi:

TODO...

Rivediamo l'esempio. Se a vuole raggiungere c usando il suo indirizzo interno in g1, cioè 10.0.1.3, deve usare come gateway e. Poi e sa che per 10.0.1.3/32 quando il pacchetto proviene da a deve usare il suo arco virtuale ei(1)-ri(1). Ora il nodo r nel frame Ethernet vede come indirizzo MAC del nodo che lo ha trasmesso quello di ei(1) che è diverso da quello di e. Quindi r sa che per 10.0.1.3/32 quando il pacchetto proviene da ei(1) deve usare come gateway c. La destinazione è raggiunta.

La creazione di una pseudo-interfaccia di rete si può fare in Linux con il modulo macvlan. Con i comandi

si crea una nuova interfaccia di rete virtuale di nome "virt0" che si appoggia all'interfaccia "eth1" ma ha un suo specifico indirizzo MAC distinto.

Nella scelta di un indirizzo MAC per una pseudo-interfaccia di rete occorre ricordare che:

Cioè l'indirizzo è nella forma ?x:??:??:??:??:?? dove x può essere 2, 6, a, e.

Verifica

Verifichiamo con un testbed. Virtualiziamo i nodi a, c, d, e, r, f. Ognuno con la sua interfaccia di rete "eth1" vede i nodi secondo il grafo riportato sopra.

Diamo i comandi:

Dopo aver dato questi comandi, le cose da verificare accedendo ai singoli nodi virtuali sono:

Se il g-nodo g1 migra, una connessione TCP tra a e c deve continuare a funzionare. Si realizzi una connessione TCP dal nodo a verso l'indirizzo interno 10.0.1.3. Si diano i seguenti comandi ai nodi a e c (che realizzano la migrazione del g-nodo g1) uno alla volta, verificando che la connessione TCP suddetta non si interrompa mai.