Hierarchical Mobile IPv6
Spécifications Techniques d'Implantation dans FreeBSD

C. CASTELLUCCIA - L. BELLIER - PROJET PLANETE - INRIA Rhône-Alpes
claude.castelluccia@inrialpes.fr

Mai 2000

Abstract

Ce document est relatif au projet MobiSecV6. Il décrit comment a été réalisé l'implémentation de la mobilité hiérarchique dans la souche Mobile IPv6 livrée par le sous projet 1. Les lecteurs de ce document devraient avoir une parfaite connaissance de Mobile IPv6 ([]), de la souche du sous projet 1 et des spécifications fonctionnelles ([]).

L'idée de base de cette implémentation est de modifier le moins possible la souche originelle. Nous nous sommes efforcés de repérer les points précis où nous avions besoin d'insérer du code, et nous avons fait appel à des fonctions, réalisées par nos soins, pour produire les effets escomptés. Ces fonctions sont écrites dans des fichiers .c figurant dans un reportoire ndpd-uhmma.
Ces fichiers sont préfixés par les initiales de la machine auquel ils sont relatifs : mh-xxx.c pour le Mobile Host, ma- pour le Mobility Agent et bs- pour la Base Station. Le xxx représente une fonctionnalité. Par exemple, ma-smooth.c va regrouper les fonctions du MA relatives au smooth handoff. A noter qu'il existe quelques fichiers mu-xxx.c qui contiennent des fonctions utilisées par plusieurs composants.

Le code ajouté à ndpd a été entouré de define. Nous avons trois define différents, un pour chaque entité. UHMMA pour le Mobile Host, uMIP pour le Mobility Agent et uMIPBS pour la Base Station.
Il est donc possible de compiler ndpd-host avec ou sans support pour HMIP, et ndpd-router pour être un MA ou une BS ou encore aucun des deux. Je rappelle ici qu'un MA ne peut pas être un Home Agent, alors qu'un BS si.

Rappels importants  : Un major move est un mouvement qui s'est effectué vers ou depuis le réseau mère. Il ne faut donc pas confondre major move avec macro move, qui est un mouvement entre deux domaines différents, par opposition à micro move qui est un mouvement à l'intérieur d'un domaine. Un major move peut donc être un micro move.
Un minor move est un mouvement dans lequel le réseau mère n'est ni le réseau d'origine ni le réseau d'arrivée. Un minor move peut être un macro move ou un micro move.
Major move et mino move sont des termes définis par l'implémentation de Mobile IPv6. Macro et micro move sont des termes définis par Hierarchical Mobile IPv6.

1  Mobile Host

1.1  Quelques variables utiles

Nous avons besoin d'un certain nombre de variables pour mémoriser les informations relatives au mode de fonctionnement du mobile. Le mobile est capable de fonctionner selon trois modes distincts.
Nous avons décider d'utiliser une batterie de fonctions dissiminées dans plusieurs fichiers c. Nous avons besoin d'avoir des variables globales. Plutôt que d'utiliser une multitude de variables globales, nous utilisons une structure qui contient toutes les variables dont on a besoin. L'avantage de cette méthode est une meilleure lisibilité du code. Notre structure s'appelle "global", il est donc facile lorsque l'on lit "global.nbBack" de savoir où et comment est définie/déclarée cette variable.

1.1.1  Liste

Voici la liste des variables utilisées avec leur fonction :

  TAILQ_HEAD(, prefix)  Vpref; /* list of voca prefix */
  char   MA_mode;              /* MA mode 1|2 */
  char   mode du mobile;        /* the current mobility mode */
  char   mode du mobile_init;   /* the user mobility mode choice */
  char   need_to_swap;         /* is set while swapping */
  char   swap_in_progress;     /*  */
  char * reemit_reg_packet;    /* registration packet */
  int    seq_num;              /* sequence number */
  short  nbBack;               /* number of waitin Back */
  struct corr     * HA;        /* Home agent */
  struct in6_addr   MA_address;/* local MA */
  struct in6_addr   MA_old;    /* previous MA */
  struct in6_addr   MA_readed; /* MA readed in the rt adv*/
  struct in6_addr   VCOA;      /* the vcoa itself */
  struct timeout  * back_timer;     /* */
  struct timeout  * reemis_timer;   /* retransmit timer */
  struct timeout  * uMIP_timer;     /* old position timer */
  u_char    MA_plen;        /* prefix length of virtual network */
  u_char    site_len;       /* site prefix length */
  u_char    reg_ret;        /* number of retransmissions */
  u_char    reg_ret_max;    /* max. number of retransmissions */
  u_short   pkt_size;       /* size of the reemission packet */

Nous utilisons dans l'implémentation un certain nombre de timers. Les durée de ces timers sont initialisées avec des valeurs par défaut. Nous offrons aux utilisateurs la possibilité d'initialiser ces valeurs avec les temps qu'il désire (cf. ). Pour stocker ces temps nous utilisons une autre structure, struct temp. Elle contient les variables suivantes :

  u_int  forward;       /* forwarding while moving between two domain */
  u_int  home;          /* forwarding when returning to home */
  u_int  lifetime;      /* default lifetime sent to a MA */
  u_int  position;      /* interval for sending old position */
  u_int  refresh;       /* default refresh */
  u_int  retransmission;/* interval between two registrations */
  u_int  smooth;        /* interval between two smooth handoffs */

1.1.2  Initialisation

ndpd-host possède deux fonctions d'initialisation. La première est pour le protocole NDP et la seconde est pour la mobilité. C'est à l'intérieur de celle-ci que nous faisons appel à notre propre fonction d'initialisation, qui va positionner quelques variables ; on initialise les différentes adresses que nous utiliserons par la suite à l'adresse indéterminée et le compteur de séquence à zéro.

Les valeurs des temporisations sont entrées par l'utilisateur par l'intermédiaire du fichier /etc/mobile6. Nous utilisons également cette méthode pour

Pour affecter ces variables nous utilisons donc des fonctions que nous avons été obligé de laisser dans le fichier mc-file.c de MIP. En effet, le déplacement de nos fonctions dans un fichier à part entraine beaucoup de complications (à cause notament, d'une multitude de variables statiques et globales au fichier). Nous avons donc ajouté nos fonctions directement dans mc-file.c, encadrées par un define.
Nous ne précisons pas ici les algorithmes utilisés, car il sagit d'une simple copie de ce de Mobile IPv6.

1.2  Détection de mouvement

Ce qui change dans l'approche hiérarchique, c'est le comportement du mobile après un mouvement. Nous avons donc laisser les procédures de détection de mouvement faire leur travail et nous avons insérer quelques tests avant d'exécuter l'action de base consécutive à la détection de mouvement (ie. envoi de binding aux correspondants) pour prendre en compte la mobilité hiérarchique.

Les fonctions qui sont appelées après un mouvement sont major_move et minor_move. Un major move est un mouvement dans lequel intervient le réseau mère et un minor move est un mouvement entre deux réseaux visités.
Ces deux fonctions mettent à jour un certain nombre de variables (telle la care-of) pour prendre en compte la nouvelle position, puis font appel à mobile_move.
mobile_move va envoyer les binding updates, et ce selon le standard Mobile IPv6. C'est donc autour de cet appel que nous allons travailler.
Il faut ici tenir compte du mode de mobilité actuel.

Ceci est valable pour major_move et minor_move.
Les choses sont en fait plus complexe car il faut tenir compte des disponibilités des modes après un mouvement. Nous reviendrons sur cet aspect dans la section .

si mode du mobile == 2 alors
  envoyer enregistrement au MA
  terminer
si mode du mobile == 1 alors
  envoyer enregistrement au MA
gérer la mobilité selon MIP

Un point à aborder ici est l'utilisation des routers adv. pour la détection de mouvement. Le mobile reçoit un router adv. d'un routeur qu'il ne connait pas. Il en clonclut qu'il a peut être effectuer un mouvement. Il sollicite alors l'ancien routeur. Si celui-ci répond, pas de mouvement. Si l'ancien ne répond pas, alors mouvement. Les procédures de gestion de mouvement sont appelées.
Le protocole HMIP véhicule l'adresse du MA local à l'intérieur des routers adv. Dans la fonction qui traite le router adv.(recv_rtadv de icmp.c), nous regardons s'il apparait une option MA. Si oui nous stockons l'adresse du MA et le mode du MA dans des variables temporaires. Ces variables seront utilisées pour notre gestion de micro/macro mobilité.

1.3  Enregistrement au Mobility Agent

Pour suivre la phylosophie du code MIP, nous avons créer deux fonctions : send_uhmma_major_reg et send_uhmma_minor_reg. Ces fonctions se trouvent dans mh-reg.c, elles seront appelée par major_move et minor_move.

1.3.1  send_uhmma_major_reg

Nous sommes ici en présence d'un mouvement vers ou depuis le réseau mère.

Si nous venons du réseau mère, il faut :

Note  : pour la gestion des ack se référer à la section . nous ne parlons pas des ack dans le cas du mode 1. Nous utilisons pour cela les mécanismes de MIPv6 qui fonctionne très bien pour ce mode.

Si nous arrivons sur le réseau mère :

1.3.2  build_send_reg

Nous utilisons cette fonction pour envoyer un paquet d'enregistrement au MA courant. C'est donc la variable globale MA courant qui est utilisée pour destination du paquet.
Cette fonction reçoit en paramètre un flag qui indique si oui ou non le processus de retransmission du paquet doit être engagé ou non.
Ce processus est réalisé en sauvegardant une copie du paquet d'enregistrement en mémoire (ainsi que sa taille) et en lançant un timer2 avec en traitant la fonction resend_reg.
Lorsque le timer expire, le traitant est appelé. Ce traitant augmente le compteur de séquence (dans la variable ET dans le paquet lui même), renvoie le paquet et relance le même timer avec lui même en traitant. On créait ainsi un processus de ré émission qu'il est possible de stopper par l'arrivée des ack escomptés (cf. ). Nous verrons en l'algorithme de cette fonction. parle des changements de mode, en effet il est possible qu'un mobile abandonne sa phase d'enregistrement qui semble infructueuse pour passer en mode MIP.

1.3.3  clear_back

Lorsque le mobile retourne sur le réseau mère après x mouvements, il faut le replacer dans un état satisfaisant (comme s'il venait de booter sur le réseau mère) ; retirer les adresses virtuelles, initialiser quelques variables. Nous ne pouvons pas effacer les adresses de HMIP dès que l'on arrive sur le réseau mère, car nous les utilisons pour faire divers controles lors de la reception des ack. Nous replaçons à zéro (adresse indéterminée) les quelques variables : MA_address, MA_old et VCOA.

Note  : les VCOA ne sont pas retirer ici car elles ont été dépréciées lors de la gestion du mouvement. Le temp de dépréciation et le temps donné à clear_back avant son exécution est le même, ainsi les deux actions se dérouleront simultanément.

1.3.4  send_uhmma_minor_reg

Nous gérons ici les mouvements entre deux réseaux. Nous devons savoir si ces deux réseaux appartiennent au même domaine ou non, car le traitement diffère si l'on utilise la gestion hiérarchique.

Si les deux réseaux sont du même domaine :

Si les deux réseaux appartiennent à des domaines différents :

update_cn_list  : la mise à jour des correspondants est faite pour détecter s'il faut envoyer une PCOA ou un VCOA dans les binding updates. Il est important de faire ceci ici, car en sortie de cette fonction nous allons enchainer sur l'envoi des binding updates (cf. 1.2). Cette fonction est une boucle qui passe en revue tous les correspondants. Pour chacun d'entre eux, on regarde si ce correspondant est dans le domaine actuel, si oui le champ VCOA de la structure doit être initialisé avec l'adresse indeterminée. Sinon, la nouvelle VCOA est copié dans ce champ. Si le mobile fonctionne en mode MIP, ce champ est obligatoirement initialisé à l'adresse indeterminée. Ce champ sera utilisé lors de l'envoi de binding updates (cf. ).

1.3.5  Maintien de position

Nous parlons de cette fonction ici, bien qu'elle soit effectivement activée par le processus de réception des ack.
Cette fonction a pout but d'envoyer périodiquement un paquet binding update au MA pour lui confirmer que le mobile est toujours à sa place. Si cela n'est pas fait le mobile se vera retiré de la liste des mobiles et ne sera donc plus géré localement. Ce paquet est en fait identique à un binding update sauf qu'il contient le flag OLD_POSITION_FLAG. Nous copions donc le code d'envoi de binding dans MIP pour notre fonction. Nous y ajoutons simplement en fin, le lancement du timer uMIP_timer avec le traitant send_old_position. Ainsi cette fonction se relance indéfiniment. On peut évidement stopper ce processus en détruisant le timer. Cette fonction incrémente le compteur de séquence à chaque occurence, elle utilise la PCOA pour remplir le champ source du paquet et l'adresse du MA local pour le champ destination.

1.4  Politique d'envoi des bindings

Ce paragraphe porte uniquement sur le mode 1 de fonctionnement, dans le cas 2, les binding updates sont envoyés par le MA. L'envoi est assuré par la fonction mobile_move. Cette fonction est divisée en trois partie :

Note importante  : rappelons nous que nous ne pouvons arriver dans cette fonction que si nous fonctionnons en mode MODE1 ou MIP.

Eliminons le cas retour sur réseau mère, car le code pour MIP et HMIP est le même : se dé enregistrer de tous les correspondants - > pas de modification.
Par contre pour les deux autres cas, nous devons tester l'état du mobile et le type de mouvement avant de prendre une décision quant à l'envoi d'un binding update. Ces tests se placent devant le code d'envoi de binding updates de MIP.

si mobility mode == MODE1 alors
  si MA précédent != MA courant alors
    envoyer binding
sinon
  envoyer binding (code normal de MIPv6)
Les fonctions d'envoi de binding (il y en a deux, une étant spécifique au HA) sont send_bnd_upd et send_home_reg. Ces fonctions ont été entièrement réécrites dans le fichier mh-send.c. C'est pourquoi en début de mc-send.c nous avons ajouté un ifndef UHMMA pour exclure tout le fichier.
Notre fonction send_bnd_upd peut ajouter la VCOA dans le binding si cela est nécessaire. Nous avons ajouter une adresse dans la structure corr ; VCOA. Cette adresse est mise à jour après un mouvement dans send_uhmma_major_reg ou send_uhmma_minor_reg par une fonction update_cn_list(cf. 1.3.4). Ainsi send_bnd_upd n'a plus qu'à consulter cette adresse. Si elle est indéterminée alors il faut construire un binding MIP, sinon il faut ajouter cette VCOA dans le binding update à l'emplacement adéquat. Si notre mobile tourne en mode MIP, il faut que tous les champs VCOA des structures de correspondant contiennent l'adresse indéterminée.
si cop.VCOA est l'adresse indéterminée alors
  envoyer binding classique
sinon
  envoyer binding avec VCOA

Notre fonction send_home_reg fonctionne selon le même algorithme.

1.5  Gestion des ack attendus

La première chose à aborder ici est le fait que les ack de MIP et du mode 1 sont entièrement gérés par le code de MIP que nous n'avons pas modifié. Nous ne nous en préoccupons pas. Nous verrons en détails la gestion des ack en provenance du MA pour le mode 1 et des ack. du HA et du MA pour le mode 2.
Selon le type de mouvement que l'on vient d'effectuer, nous devons nous attendre à recevoir un ou deux ack. Le MA acquitte toujours, le HA aussi, mais comme il ne sera prévenu (par envoi de binding) qu'en cas de mobilité inter domaine ou de major move, il faut se préparer à parfois ne pas être acquitté par le HA.
Pour savoir exactement où l'on en est, nous utilisons une variable nbBack pour représenter l'état d'attente dans lequel on se trouve.

-1 -> le mobile est en attente d'un seul ack, consécutivement à 
      un micro mouvement.
 0 -> aucun ack attendu.
 1 -> le mobile est en attente de deux ack après un macro
      mouvement, le ack du MA est déjà arrivé.
 2 -> le mobile est en attente de deux ack après un macro
      mouvement, le ack du HA est déjà arrivé.
 3 -> le mobile est en attente de deux ack après un macro
      mouvement.
D'autre cas viendront enrichir ceux-ci lorsque nous parlerons de changement de mode (cf ).

Dans la souche FreeBSD un paquet contenant une/plusieurs destination option(s), est remonté par le noyau dans le démon ndpd-host. Il est traité dans la fonction recv_destopt, qui dirige le paquet vers d'autres fonctions, recv_bnd_upd ou autre. Dans notre cas, c'est recv_bnd_ack qui nous intéresse. En début de cette fonction nous ajoutons un appel à une de nos fonctions :

si check_uhmma_back(paquet) == 1 alors
  terminer
sinon
  traiter paquet selon MIP

Notre fonction va analyser le paquet et déduire s'il s'agit d'un ack pour UHMMA ou pour MIP. S'il s'agit d'un ack pour HMIP, il sera traité. La fonction retourne 1 s'il s'agit de HMIP, ainsi recv_bnd_ack saura qu'il ne faut traiter une nouvelle fois ce paquet.

check_uhmma_back  

si mode du mobile == MODE2 alors
  si source du paquet == MA local alors
    si numéro de séquence du paquet < compteur de séquence alors
      retourner 1
    si status du paquet != accepté alors
      retourner 1
    cas nbBack parmis
      -1 : lancer hmip_ack
       2 : lancer hmip_ack
       3 : nbBack <- 1
           si numéro de séquence du paquet > compteur de séquence alors
             compteur de séquence <- numéro de séquence du paquet         *1
    retourner 1
        
  sinon si source du paquet == HA alors
    si numéro de séquence du paquet < compteur de séquence alors
      retourner 1
    si status du paquet != accepté alors
      retourner 1
    cas nbBack parmis
       3 : nbBack <- 2
       1 : lancer hmip_ack
    retourner 1
	
  sinon retourner 0
        
sinon si mode du mobile == MODE1 alors
  si source == MA local alors
    si numéro de séquence du paquet < compteur de séquence alors
      retourner 1
    si status du paquet != accepté alors
      retourner 1
    lancer hmip_ack  
    retourner 1
 
  sinon retourner 0

sinon 
  retourner 0


fonction hmip_ack
  stopper reemit_timer
  sauvegarder MA local dans MA précédent
  libérer mémoire du paquet d'enregistrement
  si réseau courant != réseau mère et mode != MIP_MODE alors
    lancer uMIP_timer avec send_old_position en traitant
  nbBack <- 0
  si numéro de séquence du paquet > compteur de séquence alors
    compteur de séquence <- numéro de séquence du paquet                  *1

  1. nous procédons ici à la synchronisation du compteur de séquence avec le numéro de séquence lu dans le paquet reçu. Ceci est fort util, car le rythme d'envoi des home registrations vers le HA par le MA est inconnu du mobile. Impossible de connaitre ce numéro. Impossible de vérifier le numéro de séquence du HA. Le MA va donc placer le numéro de séquence du HA dans le ack du mobile. Ainsi le mobile peut se synchroniser et vérifier le ack du HA.

Cette fonction va par la suite s'enrichir de nouveaux cas relatifs aux changements de mode. Nous les verons dans le paragraphe correspondant (cf. ).

Note  : send_old_position lancée ici est définie en 1.3.5.

1.6  Changement de mode

Nous allons décrire ici comment détecte t'on qu'il faut changer de mode et les mécanismes de changement de mode.

1.6.1  Détection

Il est nécessaire de changer de mode dans plusieurs cas. Il est importante de comprendre qu'il existe une hiérarchie dans les modes. MIP est le mode le plus bas, MODE1 est le mode intermédiaire et MODE2 est le mode le plus grand. Lorsque l'utilisateur démarre son mobile, il lui communique son mode de prédilection. Le mobile fera en sorte de toujours utiliser le mode le plus proche dans l'ordre défini ci-dessus. A noter qu'un changement de mode se fait toujours après un mouvement, et avant la résolution de celui-ci.
Raisons de changement de mode :

Nous nous servons de l'option MA lue ou absente dans les router adv. reçus (cf. 1.2) pour détecter si un changement de mode est nécessaire. Cette détection est faire en deux endroits différents.

major_move  : cette fonction est divisée en deux. La première partie traite les mouvements depuis le réseau mère vers un réseau visité, l'autre partie traite les mouvements qui rammènent le mobile sur son réseau mère. Dans cette dernière il n'y a pas de changement de mode possible. Le mobile doit simplement se dé enregistrer proprement par rapport à sa dernière position. Le mode de mobilité sur le réseau mère n'a pas d'utilité.
Dans la première partie, avant la conditionnelle nous allons vérifier que le réseau sur lequel nous arrivons possède un MA et si ce MA peut satisfaire le mode désiré par l'utilisateur. Nous voyons ici que ces changements de mode se font toujours vers un mode inférieur. Notons qu'il n'y a pas de code spécifique de changement de mode à réaliser. En effet, nous venons de notre réseau mère, où nous n'avions pas de mobilité. Nous pouvons tout simplement changer le mode de mobilité actuelle et utiliser les procédures habituelles de gestion de mouvements.

si MA local == abscent alors
  si mode du mobile > MIP alors
    mode du mobile <- MIP
  gérer mobilité selon MIP
  terminer

si mobility mode == MODE2 alors
  si mode du MA == MODE1 alors
    mode du mobile <- MODE1
    augmenter le compteur de séquence
    envoyer enregistrement au MA
    gérer mobilité selon MIP
    terminer
  sinon
    augmenter le compteur de séquence
    envoyer enregistrement au MA
    terminer

si mobility mode == MODE1 alors
  augmenter le compteur de séquence
  envoyer enregistrement au MA

gérer mobilité selon MIP

minor_move  : dans cette fonction nous allons expliquer comment il est possible de changer de mode pour tendre vers le choix de l'utilisateur. A l'opposé de major_move nous allons ici changer de mode vers un mode supérieur. Notre algorithme se place juste avant la conditionnelle que nous avons produite dans 1.2. Il convient également de vérifier si l'on doit changer de mode pour un mode inférieur. On rejoint alors la même forme d'algorithme que pour major_move.

si mode du mobile < mode du MA alors
  si mode du mobile < mode initial de l'utilisateur alors
    si mode initial de l'utilisateur > mode du MA alors
      need_to_swap <- mode du MA
    sinon
      need_to_swap <- mode initial de l'utilisateur
    lancer la fonction swap_mode
    terminer

si mobility mode == MODE2 alors
  lancer send_uhmma_minor_reg
  terminer
si mobility mode == MODE1 alors
  lancer send_uhmma_minor_reg

gérer la mobilité selon MIP        
Au contraire de major_move, on vient d'un autre réseau où la mobilité était traitée. Le mobile était donc configuré (variables, adresses, etc.). Nous ne pouvons nous contenter de changer de mode, il faut exécuter du code pour mettre à jour la configuration ; nous utilisons une fonction swap_mode.
La variable need_to_swap est utilisée dans la fonction swap_mode, définie ci-dessous dans .

send_uhmma_minor_reg   : dans la section de cette fonction qui traite des mouvements inter domaine, nous allons ajouter au début du code pour vérifier que le mode désiré par le mobile est disponible. Si ce n'est pas le cas, le mobile change de mode.

si MA local == abscent alors
  si mode du mobile > MIP alors
    need_to_swap <- MIP_MODE
    lancer la fonction swap_mode
    terminer

si mobility mode == MODE2 alors
  si mode du MA == MODE1 alors
    need_to_swap <- MODE1
    lancer la fonction swap_mode
    terminer

Trop de ré émissions  : une autre façon de déterminer si un changement de mode est nécessaire, est de compter le nombre de ré émissions d'envoi d'enregistrement. Nous avons préciser en 1.1.2 que l'utilisateur pouvait spécifier le nombre de retransmissions maximal qu'il désirait avant que son mobile ne change de mode. Cette décision de changement de mode est faite dans la fonction resend_uhmma_reg, dont nous avons brièvement parlé en 1.3.2.

augmenter nombre de retransmission 
si nombre de retransmissions >= nombre de retransmissions max alors
  lancer stop_HMIP
  terminer
incrémenter compteur de séquence
incrémenter numéro de séquence dans le paquet sauvegardé
renvoyer paquet d'enregistrement
relancer timer associé à la ré émission avec resend_uhmma_reg en traitant
La fonction stop_HMIP est décrite en . Il ne faut pas oublier d'initialiser la variable nombre de retransmissions à 0 lorsque l'on envoie le premier paquet d'enregistrement (dans build_send_reg 1.3.2).

1.6.2  Mécanismes de changement de mode

Ces mécanismes sont regroupés dans deux fonctions. La première, swap_mode, tient compte du mode de mobilité actuel, et du mode vers lequel on doit changer (contenu dans need_to_swap). En fonction de ces deux paramètres, elle effectue le bon traitement.

swap_mode  

cas mode du mobile parmis
  MIP_MODE :
    cas need_to_swap parmis
          MODE1 :
            mode du mobile <- MODE1
            augmenter le compteur de séquence
            envoyer paquet d'enregistrement au MA local
            mettre à jour liste des correspondants                    *1
            gérer la mobilité selon MIP 
                (envoi de bindings aux correspondants)
                          
          MODE2 :
            nbBack <- 200                                             *3
            copier la nouvelle careof dans le champ prévue à cet effet 
                   dans la structure HA
            mode du mobile <- MODE2_FROM_MIP
            augmenter le compteur de séquence
            envoyer paquet d'enregistrement au MA local
            envoyer liste de correspondants au MA local               *2

  MODE1 :
    cas need_to_swap parmis
          MIP_MODE :
            nbBack <- 200                                             *3
            copier la nouvelle careof dans le champ prévue à cet effet 
                               dans la structure HA
            mode du mobile <- MODE2_FROM_MIP
            augmenter le compteur de séquence
            envoyer paquet d'enregistrement au MA local
            envoyer liste de correspondants au MA local               *2

          MODE2 :
            envoyer forward au MA précédent                           *5
            stopper uMIP_timer, reemit_timer et back_timer
            effacer adresses de MA, MA précédent et VCOA
            déprécier la VCOA des interfaces réseau
            mode du mobile <- MIP_MODE
            mettre à jour liste des correspondants                    *1

  MODE2 :
    cas need_to_swap parmis
          MODE1 :
            envoyer smooth handoff au MA précédent                    *4
            nbBack <- 21                                              *3
                
          MIP_MODE :
            envoyer smooth handoff au MA précédent                    *4
            nbBack <- 20                                              *3

Commentaires  : nous avons repéré certains points déliquats de cet algorithme par des chiffres, nous allons maintenant expliquer ces points sensibles.

  1. nous utilisons la même fonction update_cn_list définie en 1.3.4.
  2. nous procédons de la même façon que le ferait un MA pour transférer une liste de correspondants lors d'un smooth handoff (cf ).
  3. nous utilisons de nouvelles valeurs pour nbBack, et ce de façon à bien repérer les cas de changement de mode dans la procédure de réception des ack. Ceci est important car seulement une partie du traitement est faite par swap_mode. La seconde partie sera faite dans check_uhmma_back.
  4. nous utilisons la même fonction que celle utilisée dans un MA (cf ).
  5. nous utilisons la même fonction que celle utilisée dans un MA (cf ).

stop_HMIP  : cette fonction est appelée consécutivement à la détection de trop nombreuses ré émissions d'enregistrement.

nbBACK <- 0
stopper timer associé à la ré émission des enregistrements
libérer mémoire occupée par le paquet d'enregistrement

si on arrive du réseau mère alors
  retirer la VCOA des interfaces réseau
  mode du mobile <- MIP_MODE
  si mode du mobile == MODE2 alors
    envoyer une home registration au home agent
  sinon le mode est MODE1
    simuler un minor move en utilisant les procédures de mouvement MIP     *1

sinon on arrive d'un autre réseau
  sauvegarder le mode courant dans old_mode
  need_to_swap <- MIP_MODE
  lancer swap_mode                                                         *2
  si old_mode == MODE1 alors
    simuler un minor move en utilisant les procédures de mouvement MIP     *3

  1. étant donné que le mobile tourne en mode 1, après son mouvement il n'a pas attendu de recevoir l'acquitement du MA local pour envoyer une home registration au home agent. Et il a fait ceci en incluant sa VCOA dans le binding. Or si le MA ne répond pas à l'enregistrement, il y a de grandes chances que le MA n'est pas enregistré le mobile. Ce qui signifie que le proxy VCOA/PCOA n'est pas en place. Le mobile est isolé. Il doit donc maintenant envoyer un nouveau binding update avec cette fois sa PCOA. Nous ré utilisons le code de MIPv6 pour cela.
  2. swap_mode est définie en 1.6.2.
  3. nous sommes dans le même cas que le 1-, sauf que le mobile venant d'un autre site, possède peut être déjà d'autres correspondants, en plus de son home agent. Il faut donc envoyer un binding update à chacun d'entre eux.

1.6.3  Réception des ack.

La fin d'une procédure de swap se fait dans la fonction check_uhmma_back, lorsque l'on a reçu les ack escomptés pour valider notre changement de mode. Nous ajoutons donc de nouveaux cas dans cette fonction initialement définie en 1.3.2.

20 ->  le mobile est en attente d'un ack du MA précédent suite à un
       changement de mode MODE2 vers MODE1 et donc un smooth handoff.
       Ce ack contient une liste de correspondants.
21 ->  le mobile est en attente d'un ack du MA précédent suite à un
       changement de mode MODE2 vers MIP et donc un smooth handoff.
       Ce ack contient une liste de correspondants.
200 -> le mobile est en attente du ack du MA car il vient de lui
       envoyer sa liste de correspondants. Nous devons également
       attendre le ack du HA qui indique que celui-ci a bien 
       enregistré la nouvelle position.
L'algorithme suivant est à insérer dans celui défini auparavant, dans le cas parmis de la conditionnelle si mode du mobile == MODE2 alors si source du paquet == MA local alors ...
      20 : décoder et stocker liste de correspondants
           mode du mobile <- MIP_MODE
           mettre à jour liste de correspondants
           gérer la mobilité selon MIP
           compteur de séquence <- 0
           effacer les adresses VCOA, MA et MA précédent
           stopper les timers HMIP
           libérer le paquets de ré émission
           déprécier les VCOA des interfaces réseau
      21 : décoder et stocker liste de correpondants
           mode du mobile <- MODE1
           si major move alors
             lancer send_uhmma_major_reg
           sinon
             lancer send_uhmma_minor_reg
           mettre à jour liste de correspondants
           gérer la mobilité selon MIP
           si numéro de séquence > compteur de séquence alors
             compteur de séquence <- numéro de séquence                   *1
     200 : nbBACK <- 100

  1. nous procédons ici à la synchronisation du compteur de séquence avec le numéro de séquence lu dans le paquet reçu. Ceci est fort util, car le rythme d'envoi des home registrations vers le HA par le MA est inconnu du mobile. Impossible de connaitre ce numéro. Impossible de vérifier le numéro de séquence du HA. Le MA va donc placer le numéro de séquence du HA dans le ack du mobile. Ainsi le mobile peut se synchroniser et vérifier le ack du HA.

Plaçons maintenant un nouveau cas dans le cas parmis si source du paquet == HA, et toujours dans le mode MODE2.

     200 :
     100 : retirer les correspondants de la liste des correspondants
           lancer hmip_ack

Commentaire  : dans le cas de reception du HA, nous prenons en compte deux valeurs : 100, qui signifie que le ack du MA est arrivé, et 200, qui précise que le ack du MA n'est pas encore arrivé. Il est peut être perdu, ou coincé dans une congestion. Nous considérons cependant que la situation est régulière et que le ack du MA n'est pas nécessaire, car si nous avons le ack du HA c'est que le MA a bien reçu la liste, a enregistré le mobile et a envoyé une home registration.

1.7  Changement d'interfaces

Le changement d'interface est un mouvement. Car le changement de cartes s'accompagne d'un changement d'adresse MAC, donc d'EUI64, donc d'adresse temporaire.

Exemple :  un mobile est sur son réseau mère connecté par une interface ethernet. Il change d'interface pour une autre carte, elle aussi connectée sur le réseau mère. Ce changement est un mouvement, le mobile va s'enregistrer auprès de son home agent en utilisant une adresse temporaire composée avec l'EUI64 de la nouvelle carte réseau.

1.7.1  mobile_chgif

Les mouvements par changement de cartes ne sont pas supportés par les procédures habituelles (major_move et minor_move). Ils sont gérés dans la fonction mobile_chgif. A l'intérieur de cette fonction nous allons apporter des modifications pour prendre en compte la mobilité hiérarchique.
Cette fonction traite plusieurs ca, que nous allons passer en revue :

Le mobile n'a plus d'interface  : dans ce cas nous allons détruire les préfixes virtuels que nous sauvegardons dans une liste à part. En effet, si l'interface retirée est déclarée comme "removable", le code de Mobile IPv6 retire toutes les adresses IPv6 de l'interface à l'ejection. Nous devons également nettoyer nos listes d'adresses virtuelles.
Dans la conditionnelle if(def_if == NULL) nous ajoutons

parcourir liste des VCOA
    retirer VCOA des interfaces
    retirer VCOA de la liste des VCOA
Nottons que nous procédons au retrait immédiat des préfixes, et non à la dépréciation de ceux-ci.

Le mobile obtient une nouvelle interface :  en fin de fonction, les procédures de gestion de mouvement Mobile IPv6 sont appelées. Nous devons ici placer nos conditionnelles pour tenir compte des modes de fonctionnement et des types de mouvements.
Les opérations ne sont pas triviales car il faut tenir compte du fait, que le mouvement peut nous ammener à changer de mode de fonctionnement. Nous allons regarder le mode de fonctionnement actuel. Si ce mode est 1 ou 2, nous allons faire appel à une fonction uhmma_move_mode. Cette fonction va gérer le mouvement en tenant compte d'un changement de mode éventuel. Si le mode actuel est MIP, nous devons exécuter le code de Mobile IPv6 sauf si le mobile désire fonctionner selon un mode 1 ou 2, auquel cas un changement de mode est possible, nous appelons uhmma_move_mode.
mobile_chgif
Cette fonction va nous rendre un résultat qui indique si le code de Mobile IPv6 doit être exécuté ou non. Ce code est en fait la gestion du mouvement pour tous les correspondants.

si mode du mobile == MODE1 ou MODE2
   OU (mode du mobile == MIP_MODE ET
       (mode intial == MODE1 ou MODE2)
      )
alors
  si uhmma_move_mode == 0 alors
      terminer 
  si mode du mobile == MODE2 alors
      terminer

code de Mobile IPv6
uhmma_move_mode
Dans cette fonction nous traitons :

si le réseau visité est le réseau mère alors
  send_uhmma_major_reg
  retourner 1

si MA précédent == adresse indeterminée alors                            *1
  si MA local == abscent alors
      mode du mobile <- MIP_MODE
      retourner 1

  si mode du mobile == MODE2 alors
    si mode du MA == MODE1 alors
      mode du mobile <- MODE1
      lancer send_uhmma_major_reg
      retourner 1
    sinon
      lancer send_uhmma_major_reg
      retourner 0

  si mode du mobile == MIP_MODE alors
    lancer send_uhmma_major_reg
    retourner 1
    
  si mode du mobile == MIP_MODE alors
    si mode du mobile < mode intial alors
      si mode initial > mode du MA alors
        need_to_swap <- mode du MA
      sinon
        need_to_swap <- mode initial
      lancer swap_mode
      retourner 0
    sinon                                                                *2
      retourner 1

si macro mouvement alors
    si mode du mobile < mode intial alors
      si mode initial > mode du MA alors
        need_to_swap <- mode du MA
      sinon
        need_to_swap <- mode initial
      lancer swap_mode
      retourner 0

lancer send_uhmma_minor_reg
retourner 1

2  Mobility Agent

2.1  Initialisation

Tout comme pour le mobile, nous utilisons des variables globales et le fichier /etc/gateway6 pour initialiser certaines d'entre elles.

2.1.1  Variables

extern char   MA_op;        /* mode 1 or 2 */
extern char	  max_retrans;  /* number max of smooth retransmissions */
extern char	  verboseU;	    /* verbose for UHMMA only */
extern int	  socket_bpf;   /* socket for CN detection */
extern u_char  site_len;    /* length of the site prefix */
extern u_short charge;      /* the charge */
extern struct in6_addr    MA_address;       /* address on the virtual prefix */
extern struct temp_global temp;	            /* list of timer's vallues */
extern struct timeout *   MA_annonce_timer;	/* timer for sending ma annonce */
extern struct Vprefix     VirtualNetwork;   /* virtual network data */
TAILQ_HEAD(, BaseStation) listBS;   /* MA data are sent to this addresses */
TAILQ_HEAD(, MobilityAgent)listMA;  /* list of MA on the virtual link */
TAILQ_HEAD( ,mobile)      listMH;   /* list of managed mobile hosts */
TAILQ_HEAD(, WBACK)       waitingBack; /* list for smooth handoff */

2.1.2  /etc/gateway6

Nous utilisons la même méthode que pour le mobile (vue en 1.1.2). Cette méthode nous sert à initialiser :

Pour plus de détails sur la configuration consulter le document [].

2.2  Enregistrement des mobiles

2.2.1  Réception

Le paquet d'enregistrement d'un mobile contient deux destination options ; un binding update et une home address. Un tel paquet arrivant dans un MA sera remonté par le kernel dans le démon ndpd-router. Là il sera traité dans la fonction recv_destopt. Cette fonction sert à analyser le paquet arrivant et à lancer la fonction adéquate pour son traitement. Jusqu'à présent un paquet contenant une destination option binding update était passé en paramêtre à la fonction recv_bnd_upd. Nous allons devoir identifier les paquets qui sont des enregistrements MHIP et non des binding updates MIPv6, et les traiter dans une nouvelle fonction recv_uhmma_reg.
recv_destopt est composée d'une boucle de décodage des options. Cette boucle parcours le paquet pour traiter toutes les options. Elle est composée d'un cas parmis. Lorsque le type de l'option est un binding update, nous regardons si la taille de cette option est la taille d'un enregistrement HMIP (car un paquet d'enregistrement HMIP fait toujours la même taille). Si cette option correspond, on positionne un flag. Nous ne pouvons pas lancer la fonction de traitement immédiatement, car nous avons besoin de l'option home address, qui se situe quelque part en aval dans la chaine des options.
Lorsque l'on a parcouru toutes les options, on sort de la boucle. C'est à cet instant que l'on utilise l'algorithme ci-dessous :

si flag == 1 alors
  si machine local est un MA en mode 1 ou 2 alors
    lancer recv_uhmma_reg
  sinon
    envoyer un binding ack à l'émetteur avec status d'erreur

2.2.2  Traitement

Les mobiles enregistrés sont placés dans une liste. Cette liste contient des enregistrements de type ßtruct mobile", structure définie par MIPv6. Nous y avons réjouter plusieurs champs dont un est la liste des correspondants enregistrés pour le mobile. Un autre de ces champs est une adresse qui contient la VCOA.

fonction recv_uhmma_reg

décoder le paquet
si les options du paquet contiennent des erreurs alors
  envoyer binding ack avec message d'erreur

parcourir liste des mobiles
si le mobile est déjà enregistré dans la liste des mobiles alors
  si champ lifetime du paquet == 0 alors
    lancer kill_mobile
    terminer
  si numéro de séquence du paquet < numéro de séquence de la liste alors
    envoyer binding ack à l'émetteur avec erreur
    terminer
  
  si le mobile n'a pas changé de position (care-of) alors
    si le dernier mouvement était un macro move alors                    *1
      si le mobile est géré en mode 2 alors                              *2
        envoyer binding update au home agent du mobile
    envoyer binding ack au mobile
  
  sinon le mobile a changé de position
    détruire le tug vers l'ancienne position du mobile
    ouvrir un tug vers la nouvelle position du mobile
    sauvegarder la nouvelle position du mobile dans la liste des mobiles
    relancer le timer du mobile avec la durée lifetime du paquet et le 
             traitant kill_mobile

    si le mobile vient de retourner sur son réseau mère alors            *3
      si le mobile est géré en mode 2 alors
        numéro de séquence du HA <- numéro de séquence du paquet         *4
        envoyer binding update (H@/H@) à tous les correspondants
        retirer les correspondants de la liste des correspondants du mobile

    sinon le mobile vient d'effectuer un micro move
      si le mobile est géré en mode 2 alors
        envoyer binding update à tous les correspondants locaux
                (sauf au HA) avec la nouvelle position du mobile
    
    envoyer binding ack avec status accepté au mobile

sinon le mobile n'est pas enregistré dans la liste des mobiles
  si flags du paquet == MODE2 alors
    si le MA ne tourne pas en mode MODE2 alors
      envoyer binding ack à l'expéditeur avec erreur
      terminer

  créer enregistrement du mobile dans la liste des mobiles
  construire VCOA pour le mobile
  créer un tug vers le mobile
  créer un proxy entre VCOA et position du mobile                        *5

  si le mobile vient de son réseau mère alors                            *6
    si le mobile demande un enregistrement en mode 2 alors
      créer l'enregistrement du HA dans liste des correspondants du mobile
      envoyer home registration au HA avec VCOA

  sinon le mobile vient d'un autre réseau
    si le mobile est géré en mode 1 alors
      envoyer forward request au MA du réseau précédent                  *7

    sinon le mobile est géré en mode 2
      envoyer smooth handoff au MA du réseau précédent                   *8
      terminer

  si flags du paquet != MODE2_FROM_MIP alors                             *9
    envoyer binding ack au mobile
  lancer un timer de durée lifetime du paquet avec kill_mobile en traitant


  1. le mobile place dans le paquet d'enregistrement le MA qui le gérait dans son réseau précédent. Si cette adresse correspond à l'adresse du MA local, le mobile n'a pas effectué de mouvement, mais les ack escomptés ne sont pas arrivés.
  2. si le mobile tourne en mode 2 il est en attente de deux ack. Difficile de statuer sur celui qui a été perdu, celui du MA ou du HA, ou même les deux. Le MA va donc retourner un ack et provoquer le renvoi d'un ack par le HA, en lui envoyant une home registration avec les flags AH.
  3. on peut détecter ce mouvement en comparant la position du mobile avec sa home address. Je rappelle qu'un mobile qui retourne sur son réseau mère ne s'enregistre pas sur le MA local mais sur le MA qui le gérait dans le réseau précédent. Le mobile était dans le domaine du MA puis il est parti pour rentrer sur son réseau mère. Par cet enregistrement et dans le cas où le mobile utilisait le mode 2, il demande au MA de le dé enregistrer auprès de ses correspondants. S'il utilisait le mode 1, il s'agit simplement de faire suivre les paquets de l'ancienne VCOA vers la H@.
  4. par cette affectation, nous synchronisons le numéro de séquence du mobile et de son HA. En effet, le rythme des envois de maintien de position par le mobile n'est pas le même que celui des envois de home registration par le MA. Il faut que le mobile soit capable de vérifier le numéro de séquence du binding ack que son HA va lui retourner. Nous forçons donc le HA à utiliser un numéro que le mobile peux identifier.
  5. nous utilisons ici le code du HA pour intercepter et tunneller les paquets. Le MA n'est en fait qu'un HA qui redirige le trafic pour la VCOA vers la PCOA.
  6. si le mobile arrive de son réseau mère, il n'avait pas de MA pour le gérer. Il a initialisé le champ MA précédent du paquet d'enregistrement à l'adresse indéterminée. On détecte ce type de mouvement de cette façon.
  7. cf. .
  8. cf. .
  9. le mobile est en train de changer de mode. Il était dans un domaine où le mode 2 n'était pas disponible, bien qu'il désirait ce mode. Ce domaine, dans lequel le mobile vient d'arriver, dispose du mode 2. Le mobile va changer de mode pour revenir au mode 2. Il envoie donc un enregistrement avec un status particulier, pour signifier que sa liste de correspondants suit dans un autre paquet. Le MA ne doit pas acquitter de suite, mais attendre d'avoir reçu la liste cf. 1.6.

kill_mobile  : nous utilisons cette fonction pour retirer un mobile de la liste des mobiles.

si il existe des correspondants dans la liste des correspondants alors
  lancer kill_cn_list
stopper timer associé au mobile
fermer le tug vers le mobile
si il existe une procédure de smooth handoff en cours pour ce mobile alors
  stopper timer de ré émission
  libérer mémoire pour stocker le paquet de smooth handoff
retirer le mobile de la liste des mobile
Nous verrons en détails la fonction kill_cn_list dans le paragraphe sur la gestion des correspondants (cf. ).

2.2.3  Maintien de position

Le maintien de position est un paquet envoyé régulièrement par le mobile pour confirmer qu'il est toujours à sa position. Chaque mobile enregistré est associé à un timer qui lance le traitant kill_mobile s'il vient à expirer. Un paquet de maintien de position relance le timer du mobile, prolongeant ainsi sa durée de vie.
Le paquet de maintien de position est un binding update identique à celui de MIPv6 excepté qu'il contient le flag OLD_POSITION_FLAG. L'arrivée d'un tel paquet sera donc dans recv_destopt. Nous allons ajouter un test devant l'appel de recv_home_reg et recv_bnd_upd.

si flag du paquet == OLD_POSITION_FLAG alors
  si MA local tourne en mode 1 ou 2 alors
    lancer recv_old_position
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer

si flag du paquet == OPT6_BNDU_HR alors
  lancer recv_home_reg
sinon
  lancer recv_bnd_upd

recv_old_position  : cette fonction vérifie que le mobile expéditeur est effectivement dans la liste des mobiles. Si ce n'est pas le cas, elle renvoie un binding ack à cet expéditeur avec le code erreur correspondant.
Si le mobile est enregistré, il faut vérifier que le numéro de séquence du paquet est supérieur au numéro de séquence de la liste. Si ce n'est pas le cas, on retourne un binding ack avec status d'erreur approprié.
Enfin, si tout est correct, la fonction relance le timer associé au mobile et met à jour le numéro de séquence dans la liste.

2.3  Smooth handoff

Le smooth handoof est le protocole utilisé entre deux MA ou entre un MA et un mobile pour transférer une liste de correspondants après un mouvement inter domaine.

2.3.1  Envoi de smooth handoff

L'envoi d'un smooth handoff est provoqué par l'arrivé d'un enregistrement d'un mobile venant d'un autre domaine (cf. 2.2.2). Le smooth handoff est en fait un paquet binding update comme définit dans MIP sauf que le flag est : SMOOTH_FLAG. L'envoi d'un smooth handoff se résume en trois points :

2.3.2  Reception de smooth handoff

Un smooth handoff est un binding update avec un champ flag particulier. Il sera donc intercepté dans la fonction recv_destopt. Nous avons déjà parlé de cette fonction et son algorithme devient maintenant :

si flag du paquet == OLD_POSITION_FLAG alors
  si MA local tourne en mode 1 ou 2 alors
    lancer recv_old_position
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer

si flag du paquet == SMOOTH_FLAG alors
  si MA local tourne en mode 2 alors
    lancer recv_smooth
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer
  
si flag du paquet == OPT6_BNDU_HR alors
  lancer recv_home_reg
sinon
  lancer recv_bnd_upd

recv_smooth  : cette fonction va prendre en charge le transfert de la liste d'un mobile anciennement situé dans le domaine.

si mobile est enregistré dans la liste des mobiles alors
  si numéro de séquence du paquet < numéro de séquence dans la liste alors
    envoyer binding ack avec status d'erreur correspondant
  sinon
    sauvegarder numéro de séquence du paquet dans la liste
    si aucun smooth handoff pour ce mobile n'est déjà parvenu alors      *1
      fermer le tug vers l'anciennce position du mobile
      mettre à jour la position du mobile dans la liste
      ouvrir tug vers nouvelle position du mobile
    relancer timer associé au mobile avec lifetime en durée 
             et kill_mobile en traitant
    lancer send_cn_list
    si le mobile est géré en mode 2 alors    
      stopper l'envoi de binding pour tous les correspondants du mobile  *2

sinon le mobile n'est pas enregistré
  envoyer binding ack avec status d'erreur correspondant à l'expéditeur
Notez que la source du smooth handoff peut être un MA, mais aussi un mobile qui vient de changer de mode. Le MA récepteur ne fait aucune différence de traitement entre les deux. Le status d'erreur est OPT6_BNDA_CN_LIST_KO, celui de réussite OPT6_BNDA_CN_LIST_OK.

  1. il peut s'agir d'une retransmission, auquel cas il est inutile de refaire la mise à jour du mobile. Pour déceler une retransmission il suffit de comparer la position du mobile dans la liste des mobiles avec la care-of lue dans le paquet. Par cette mise à jour de la position du mobile, on procède au "forwarding" des paquets arrivant pour son ancienne VCOA vers sa nouvelle position.
  2. si le mobile est géré en mode 2, c'est le MA qui envoie les binding updates à sa place. Maintenant que le mobile est parti, il est géré par un autre MA (ou par lui même). Il ne faut donc plus envoyer des binding updates à partir de ce MA. Notez que l'on ne détruit pas de suite les enregistrements des correspondants mais que l'on ne fait que désactiver l'envoi. Ceci dans le cas où la liste de correspondants se perdrait. Le nouveau MA relancera un nouveau smooth handoff auquel nous serons en mesure de re répondre par la liste des correspondants.

send_cn_list  : cette fonction est utiliser pour envoyer la liste des correspondants.

compter le nombre de correspondants
calculer la taille du paquet à émettre
construire le paquet
envoyer le paquet
Le paquet est un binding ack avec une sub-option contenant la liste des correspondants. La construction de la liste se fait par concaténation d'enregistrements contenant les informations sur les correspondants. Ce ne sont pas les struct corr que nous concaténons. Ces structures contiennent des informations (comme des pointeurs, des timers, etc.) qu'il n'est pas pertinent de transférer. Aussi nous créons notre propre structure pour le transfert.

2.3.3  Réception d'une liste de correspondants

Nous avons vu que cette liste est contenue dans un binding ack. Elle passera donc par recv_destopt et sera finalement traitée dans recv_bnd_ack. Dans cette fonction nous allons ajouter un petit test : si le status du ack est OPT6_BNDA_CN_LIST_KO ou OPT6_BNDA_CN_LIST_OK alors lancer recv_cn_list. Attention il s'agit de la fonction recv_bnd_ack employé dans ndpd-router, donc celle qui est codée dans mh-dummy.c

recv_cn_list  :

si le status du paquet == OPT6_BNDA_CN_LIST_KO alors
  parcourir la liste des WBACK                                            *1
  si l'enregistrement est dans la liste alors
    stopper le timer de ré émission du smooth handoff associé
    sauvegarder le numéro de séquence du paquet dans la liste des mobiles
    envoyer binding ack avec status refusé au mobile
    lancer kill_mobile
    retirer la structure WBACK de la liste

sinon le status est OPT6_BNDA_CN_LIST_OK
  parcourir la liste des WBACK                                            *1
  si l'enregistrement est dans la liste alors 
    stopper le timer de ré émission du smooth handoff associé
    sauvegarder le numéro de séquence du paquet dans la liste des mobiles
    lancer store_list
    envoyer des binding updates aux correspondants                        *3
    envoyer binding ack avec status accepté au mobile
    retirer la structure WBACK de la liste

  sinon l'enregistrement n'est pas dans la liste
    parcourir liste des mobiles                                           *2
    si le mobile figure dans la liste alors
      lancer store_list
      envoyer des binding updates aux correspondants                      *3
      relancer timer associé au mobile avec lifetime du paquet en durée et
               kill_mobile en traitant
      envoyer binding ack au mobile avec status accepté

  1. un enregistrement sera considéré comme satisfaisant s'il répond à deux critères : les home addresses sont les mêmes et l'adresse de l'expéditeur est bien le MA que l'on a sauvegardé dans la structure WBACK.
  2. il s'agit là du cas d'un mobile qui vient de changer de mode MIP/MODE1 vers MODE2. Il vient lui même d'envoyer sa liste de correspondants pour être géré en mode 2.
  3. le home agent nécessite une home registration. Les correspondants situés dans ce domaine doivent recevoir un binding PCOA/H@ et les autres VCOA/H@. Notez que nous avons codé nos propres fonctions d'envoi de binding/home registration pour le MA en nous basant sur celle du mobile et en ajoutant quelques spécificités, cf .

store_list  : cette fonction est utilisée pour décoder le paquet contenant les correspondants et pour créer la liste des correspondants du mobile. Elle ne fait donc que la traduction des structures lues dans le paquet en structures de correspondants pour le mobile. Elle profite également de l'occasion pour synchroniser les numéros de séquence des correspondants avec celui du mobile. Et une dernière chose, elle détermine (en comparant l'adresse du correspondant et la position du mobile) si le ce correspondant nécessitera l'ajout d'une VCOA ou d'une PCOA dans les binding updates (cf. ).

2.4  Forward

Le protocole de forward est une version allégée du smooth handoff. Il ne transfert aucune liste et se contente de mettre en place un mécanisme de suivi des paquets depuis une ancienne position vers une nouvelle.
Nous avons vu que le lancement d'un forward se faisait dans recv_uhmma_reg. Un forward est un paquet identique à celui d'un smooth handoff (et donc à un binding update) avec le flag contenant : FORWARD_FLAG. Ceci nous ajoute un nouveau cas dans notre fonction recv_destopt.
Nous ne détaillons pas l'envoi d'un forward, car il s'agit d'un smooth handoff sans la mécanique de retransmission (simple donc :-).

Réception  

si flag du paquet == OLD_POSITION_FLAG alors
  si MA local tourne en mode 1 ou 2 alors
    lancer recv_old_position
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer

si flag du paquet == SMOOTH_FLAG alors
  si MA local tourne en mode 2 alors
    lancer recv_smooth
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer
  
si flag du paquet == FORWARD_FLAG alors
  si MA local tourne en mode 2 alors
    lancer recv_forward
  sinon
    envoyer binding ack à l'expéditeur avec status d'erreur
  terminer

si flag du paquet == OPT6_BNDU_HR alors
  lancer recv_home_reg
sinon
  lancer recv_bnd_upd
Il n'y a aucun mécanisme de retransmission et d'acquittement pour le forward. Si le protocole échoue, il en résultera la perte des hypothétiques paquets transmis par les correspondants vers l'ancienne position du mobile avant que ceux-ci n'aient reçu un nouveau binding update avec la nouvelle position.

recv_forward  

si mobile est enregistré dans la liste des mobiles alors
  si numéro de séquence du paquet < numéro de séquence dans la liste alors
    envoyer binding ack avec status d'erreur correspondant
  sinon
    sauvegarder numéro de séquence du paquet dans la liste
    fermer le tug vers l'anciennce position du mobile
    mettre à jour la position du mobile dans la liste
    ouvrir tug vers nouvelle position du mobile
    relancer timer associé au mobile avec lifetime en durée 
             et kill_mobile en traitant

sinon le mobile n'est pas enregistré
  envoyer binding ack avec status d'erreur correspondant à l'expéditeur

2.5  Gestion des correspondants

Tout cette partie est relative au mode 2 uniquement.
Les mobiles sont chainés dans une liste de struct mobile, structure définie dans MIP. Nous y avons ajouté un nouveau champ ; une liste de struct corr (également définie dans MIP) pour stocker les correspondants enregistrés de ce mobile. Cette liste contient au minimum un enregistrement, qui est le home agent.

 listMH
  |
  v
 -------   -------   -------
 | MH1 |-->| MH2 |-->| MH3 |--> NULL
 -------   -------   -------
      |         |         |
      V         V         V
    -------   -------   -------
    | HA  |   | HA  |   | HA  |
    -------   -------   -------
      |         |         |
      V         V         V
    -------             -------
    | CH1 |    NULL     | CH1 |
    -------             -------
      |                   |
      V                   V
    -------             
    | CH2 |              NULL 
    ------- 
      |
      V

     NULL
Nous avons ajouté un nouveau champ à la structure corr, le champ VCOA, qui contient la VCOA du mobile.

2.5.1  Détection

La détection de nouveaux correspondants pour un mobile enregistré est simple. Un correspondant non enregistré est un correspondant qui n'a connaissance de la position d'un mobile. Il va donc envoyer les premiers paquets vers la H@ et ceux-ci seront interceptés par le HA, puis forwardés vers la VCOA. Le MA va également rediriger ces paquets vers la PCOA. Au passage le MA peux détecter le correspondant en utilisant un simple BPF. Le filtre de ce BPF portera sur le champ "next header" de l'entête IPv6. Si celui-ci est la valeur qui correspondant à IPv6, il s'agit d'un paquet encapsulé. Il suffit maintenant de vérifier si le mobile (identifié par le champ destination du paquet encapsulé qui contient la H@) est enregistré en mode 2 dans la liste des mobiles. Si tel est le cas, il suffit d'envoyer un binding update à ce correspondant et de l'enregistrer dans la liste des correspondants du mobile. Nous verrons en qu'il faut utiliser le champ type du correspondant pour identifier le type de care-fo à envoyer au correspondant. Nous devons comparer l'adresse du correspondant avec la PCOA du mobile. S'ils sont dans le même domaine, il faudra envoyer la PCOA, la VCOA sinon.
Le BPF est ouvert dans la procédure d'initialisation du MA, si et seulement si celui-ci est lancé en mode 2. Le BPF sert pour la détection des correspondants de TOUS les mobiles enregistrés. Il est ouvert sur une socket. La boucle principale de ndpd-router scrute si des données arrivent dans les sockets ICMP, ROUTE et DESTINATION OPTION. Si des données arrivent sur une de ces sockets, la fonction correspondantes est appelée pour gérer l'événement. Nous allons ajouter un nouveau test sur notre socket BPF. Si des données arrivent, nous lancerons recv_bpf.

recv_bpf  

lire les données arrivant dans la socket bpf
parcourir liste des mobiles
si le destinataire est dans la liste alors
  si le mobile est géré en mode 2
    parcourir la liste des correspondants du mobile
    si l'expéditeur n'est pas dans la liste alors
      ajouter correspondant dans la liste des correpondants
      si le correspondant est dans le domaine alors
        le type de correspondant est NO_VCOA_NEEDED
      sinon
        le type de correspondant est VCOA_NEEDED
    envoyer un binding update à ce correspondant

2.5.2  Envoi des bindings updates

Nous avons copié les fonctions d'envoi des binding updates par le mobile pour en faire nos fonctions pour notre MA. La grande différence avec le code MIP, est que nous allons devoir inclure la care-of dans les options destination.
Lorsque nous envoyons un binding update à la place d'un mobile, nous devons savoir quelle COA mettre dans le paquet ; la VCOA ou la PCOA. Nous utilisons le champ type de la structure corr pour contenir une information qui va renseigner send_bnd_upd sur la COA à insérer ; le champ type.

Envoi  : le code d'envoi est identique à celui d'un mobile à l'exception de la composition du binding update qui doit inclure un champ care-of et d'un test sur la variable type, qui conditionne l'adresse à copier dans le champ care-of. Notons que le home agent est géré par une fonction spécifique send_home_reg. Le HA doit obligatoirement recevoir la VCOA (sauf en cas de retour sur réseau mère). Le type d'un HA ne peut donc être NO_VCOA_NEEDED.
Un binding update doit être envoyé régulièrement au correspondant pour rafraichir le cache d'association. Nous avons mis en place un mécanisme de cadencement directement inclu dans la fonction send_bnd_upd. En fin de fonction, on regarde si le timer associé au correspondant existe, si oui on le relance avec en traitant send_bnd_upd elle même, si non on le lance pour la première fois. C'est ce mécanisme qui doit être stoppé lors de la réception d'un smooth handoff ou d'un forward. Il est stoppé par destruction de ces timers.

fonction send_bnd_upd

construire paquet binding update avec champ care-of vide
cas type du correpondant parmis
  VCOA_NEEDED : copier la VCOA dans le champ care-of
  NO_VCOA_NEEDED : copier la PCOA dans le champ care-of
  HOME_NEEDED : copier la H@ dans le champ care-of
envoyer paquet au correspondant
si timer associé au correspondant existe alors
  relancer timer avec send_bnd_upd en traitant
sinon
  lancer timer avec send_bnd_upd en traitant
La durée du timer est calculée en soustrayant 15 secondes au champ lifetime de la structure correspondant. Ce champ est lui même initialisé en copiant la valeur lifetime que le mobile communique dans ses paquets d'enregistrement / maintien de position. Les 15 secondes permettent d'éviter que le correspondant n'envoie de binding request, car le mobile en mode 2 ne sait pas les gérer. Un test est fait pour vérifier que lifetime - 15 est bien supérieur strictement à zéro, si cela n'est pas le cas, le timer est lancé avec un temps de 3 secondes.

Type de care-of  : nous venons de voir que send_bnd_upd utilise le type du correspondant pour savoir quelle care-of utiliser. L'initialisation de ce champ est faite lorsque l'on place le correspondant pour la première fois dans la liste des correspondants, càd lorsque l'on reçoit une liste de correspondants après un smooth handoff 2.3.3 ou lorsque l'on détecte un nouveau correspondant 2.5.1. Cette liste sera ensuite mise à jour après chaque mouvement.
Le type du correspondant s'obtient par comparaison du préfixe de l'adresse du correspondant avec celui de la PCOA du mobile. S'ils sont identiques, le correspondant et le mobile sont dans le même domaine. Le type du correspondant est donc NO_VCOA_NEEDED, sinon il est VCOA_NEEDED.

Acknowledgement  : le draft Mobile IPv6 précise que dans l'envoi des home registrations, le flag A ßhould be set". Dans notre cas (MODE2) ce flag n'est utile que pour le premier enregistrement après un mouvement. Ensuite pour les confirmations que le MA envoie, ce flag n'est pas souhaitable car il provoque le renvoi d'un ack. Ce ack le mobile ne sera pas quoi en faire (le mobile est en attente de ack seulement après ses mouvements).
Nous allons donc mettre en place un petit protocole pour éviter les ack inutiles :

  1. au premier enregistrement du mobile, à la création de son HA par le MA dans la fonction recv_uhmma_reg, on positionne les flags AH dans la structure HA.
  2. dans la fonction send_home_registration, on regarde si cette fonction a déjà été appelée (on le détermine en testant si le timer de ré émission est déjà affecté). Si on en est au premier appel, en fin de fonction, quand on lance le timer pour les ré émissions, on retire le flag A. Ainsi dans tous les prochains passage, seul le flag H sera envoyé dans la home registration.
  3. lorsqu'un MA reçoit une liste de correspondants en provenance d'un autre MA, suite à un smooth handoff, on replace le flag A dans la structure du HA (on réalise ceci dans la fonction store_list, appelée par recv_cn_list).
  4. dans le mobile, lorsque celui-ci change de mode 2 vers x, il initie lui même un smooth handoff avec son précédent MA. Lorsqu'il reçoit sa liste de correspondants, il doit également reposionner ces flag AH pour son HA. Ceci est fait dans la fonction store_cn_list, appelée par uhmma_back_check.

2.6  Annonce d'adresse de MA

Les mobiles arrivant dans le domaine apprennent l'adresse du MA en parcourant les rt adv. Ce sont les Base stations qui ajoutent cette adresse dans leur rt adv.

2.6.1  Partage de charge

Chaque MA va comptabiliser le nombre de mobile qu'il gère. Un mobile en mode 1 équivaut à un point et un mobile en mode 2 à trois points. La charge est initialisée à zéro dans la procédure d'initialisation du MA. Le calcul de cette somme est donc fait chaque fois que :

Chaque fois que la charge est modifiée, nous faisons appel à une fonction update_MA que nous définissons ci-dessous.
Le MA va ensuite utiliser une nouvelle option des rt adv pour insérer son adresse et sa charge dans ses rt adv. Chaque MA du lien pourra donc construire une liste de MA avec la charge associée.

recv_icmp  ; c'est dans cette fonction de ndpd-routeur que nous allons ajouter cette nouvelle option, dans send_rtadv, et la traiter dans recv_rtadv. Cette option, ND_OPT_CH est composée d'un entier sur 16 bits pour la charge, et d'une adresse IPv6. L'insertion est simple, la reception est faite en ajoutant un cas dans le cas parmis de recv_rtadv. Nous décodons la charge et l'adresse et faisons appel à une fonction update_MA.

update_MA  : cette fonction va gérer la liste des MA. On lui donne un MA en paramètre. La liste des MA est une nouvelle liste globale. Lorsqu'un MA est nouveau, on l'ajoute dans la liste en le plaçant de façon à ce que la liste soit triée dans l'ordre du moins chargé vers le plus chargé. Si le MA est déjà dans la liste, on vérifie si sa charge a changé, et si besoin on le déplace dans la liste. A chaque MA nous associons un timer, qui nous servira à retirer un MA s'il ne s'est plus manifesté depuis un temps déterminé.
Notez que dans la procédure d'intialisation du MA, nous devons ajouter un enregistrement correspondant au MA local.

parcourir liste des MA
si le MA est dans la liste alors
  relancer timer associé au MA avec kill_MA en traitant
  si nouvelle charge != ancienne charge connue alors
    retirer MA de la liste
    insérer le MA dans la liste
    sauvegarder nouvelle charge dans liste des MA
sinon le MA n'est pas la liste
  créer enregistrement pour le MA
  lancer un timer associé au MA avec kill_MA en traitant
  insérer le MA dans la liste des MA
kill_mobile est une petit fonction qui retire un MA de la liste et libère sa structure.

2.6.2  Envoi d'adresse

Le MA envoie un paquet contenant son adresse et son mode de fonctionnement à une série de base stations. Cette liste est déterminée par l'administrateur lorsqu'il lance le MA. Les adresses sont entrées dans le fichier de configuration. Pour l'instant nous utiilisons un paquet avec une destination option BREQ. Mais nous comptons utiliser un binding update. L'envoi de ce paquet est faite de façon régulière. Nous utilisons donc un timer, que nous lançons pour la première fois dans la procédure d'initialisation du MA. Nous n'envoyons pas dès le boot un paquet, nous attendons quelques secondes, pour que le MA est fini sa procédure de boot (adresse, rt adv., etc.). Ensuite la fonction utilisée comme traitant procédera à l'envoi du paquet, puis relancera le timer avec elle même en traitant. Ce processus continue jusqu'à l'arrêt du MA.
Lorsque la fonction d'envoi d'annonce démarre elle consulte le premier enregistrement de la liste des MA, si et seulement si le MA local est le premier de la liste il faut envoyer une annonce de MA aux BS.

2.6.3  Arrêt du MA

Lorsque l'on stoppe le MA, la fonction uhmma_ma_cleanup émet une dernière annonce vers les stations de base en précisant l'adresse indéterminée. Ainsi, les stations de base n'ajoutent plus d'option MA address dans les rt adv.

References

[]
David B. Johnson et Charles Perkins. Mobility Support in IPv6. Internet Draft, draft-ietf-mobileip-ipv6-08.txt. Novembre 1999.
[]
Claude Castelluccia, Ludovic Bellier. Mobile IPv6 Hiérarchique - Spécifications Fonctionnelles. Novembre 1999.
[]
Claude Castelluccia, Ludovic Bellier. Hierarchical Mobile IPv6 - How To. Décembre 1999.


Footnotes:

1déprécier ne signifie pas retirer immédiatement, mais équivaut à lancer un timer pour une durée donnée. Au bout de cette durée, l'adresse sera effectivement retirée.

2dans le source de ndpd-host nous trouvons une gestion de timer opérationnelle. Nous avons donc utilisé les fonctions du fichier util.c. Pour schématiser, la boucle préincipale de ndpd-host regarde à chaque passage si un timer vient d'expirer, si oui elle lance le traitant associé. Nous avons à notre disposition des fonctions pour créer, ajouter, retirer des timers.


File translated fromTEXby TTH,version 2.56.
On 17 May 2000, 12:44.