Reseau dans gnumach

De HurdFr_Wiki
Aller à : Navigation, rechercher

Sommaire

Cheminement des paquets

Termes utilisés

  • Listener : Un listener est un programme qui ouvre un device Mach (ex: ethX) et s'enregistre avec device_set_filter(). Les listeners sont par exemple pfinet ou bpf. Chaque listener met en place un filtre, même si c'est un filtre qui laisse tout passer.


Les filtres

Il existe deux types de filtres :

  • NETF : Il s'agit de filtres internes à Mach. La validation ou non d'un paquet est binaire : accepté ou non.
  • BPF : Il s'agit de Berkeley Packet Filter. La validation est faite en renvoyant le nombre d'octets à transmettre au listener (et donc 0 si le paquet n'a pas à être transmis). Un tel filtre doit être précédé par une entête ( {BPF_BEGIN, 0, 0, 0} ).


En réception

Les paquets suivent ce chemin :

driver
  |
netif_rx() (glue code)
  |
net_packet()
  |
  ---> net_queue_{high,low}

net_ast()
  |
boucle
  |
net_deliver()
  |
récupération d'un paquet <--- net_queue_{high,low}
  |
passage dans le filtre, récupération des listeners intéressés via net_filter() ---> send_list
  |
itération sur les listeners <--- send_list
  |
envoi des paquets aux listener


  • void netif_rx(struct sk_buff *skb) ( linux/dev/glue/net.c )
  • void net_packet(struct ifnet ifp, ipc_kmsg_t kmsg, uint count, boolean_t priority) ( device/net_io.c )
  • void net_ast() ( device/net_io.c )
  • boolean_t net_deliver(boolean_t nonblocking) ( device/net_io.c )
  • void net_filter(ipc_kmsg_t kmsg, ipc_kmsg_queue_t send_list) ( device/net_io.c )


  • ipc_kmsg_queue net_queue_{high,low} ( device/net_io.c )
  • struct ipc_kmsg_queue send_list ( device/net_io.c : net_deliver() )


En sortie

Les paquets suivent ce chemin :

pfinet
  |
ethernet_xmit (glue code de pfinet)
  |
device_write()
  |
drivers linux


  • io_return_t device_write(void *d, ipc_port_t reply_port, mach_msg_type_name_t reply_port_type, dev_mode_t mode, recnum_t bn, io_buf_ptr_t data, unsigned int count, int *bytes_written) ( linux/dev/glue/net.c )


Ajout du filtrage en sortie

Il y a un problème de filtre des paquets en sortie car actuellement, quand un listener s'enregistre sur une interface avec device_set_filter(), il ne reçoit que les paquets en entrée et donc ne peut filtrer qu'en entrée. En effet, il n'y a pas de couche filtre sur le schéma de sortie.

Il faut donc réinjecter les paquets sortants dans la chaine de réception.

Les paquets suiveront alors ce chemin :

pfinet
  |
ethernet_xmit (glue code de pfinet)
          |
    device_write()
       |         |
drivers linux    net_packet() ---> net_queue_{low,high}

Problème

Survient un problème : tous les paquets réinjectés sont renvoyés à tous les listeners, même ceux qui ne souhaitent pas en disposer.

Il faut donc trouver un moyen d'indiquer dans le filtre si l'ont souhaite reçevoir les paquets sortants ou non.

Le fait que tous les paquets soient envoyés à tous les listeners est dû au fait qu'il est impossible de dissocier les paquets réinjectés de ceux entrants.

Un autre problème est que, hormis les paquets unicast, seuls les paquets broadcast (Ethernet) sont reçus, empêchant ainsi le multicast (très utilisé avec IPv6 en particulier).

Modifications

  • Connaître le sens des paquets ( device/net_io.c )

Renommage des deux files net_queue_{high,low} en net_queue_in_{high,low}.

Ajout de deux files net_queue_out_{high,low}.

Changement du header de net_packet : ajout du paramètre boolean_t way qui prend soit PACKET_IN ou PACKET_OUT (cf device/net_io.h).

Les paquets vont donc maintenant suivre ceci :

device_write()                               netif_rx()
        |                                         |
net_packet(PACKET_OUT)                   net_packet(PACKET_IN)
        |                                         |
        ---> net_queue_out_{high,low}             ---> net_queue_in_{high,low}


On peut donc maintenant connaître la provenance des paquets

  • Distribution des paquets ( device/net_io.c )
net_ast()
  |
boucle
  |
net_deliver()
  |
récupération d'un paquet <--- net_queue_{in,out}_{high,low}
  |
passage dans le filtre, récupération des listeners intéressés via net_filter() ---> send_list
  |
itération sur les listeners <--- send_list
  |
envoi des paquets aux listener
Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils