Netzwerktreiber


... [ Seminar Linux und Apache ] ... [ Thema Gerätetreiber unter Linux 2.4 ] ... [ Weitere Treiberklassen ] ...

Übersicht: Netzwerktreiber


Definition

Jede Übertragung in einem Netzwerk läuft über ein Interface, also ein Gerät, das in der Lage ist, Daten mit anderen auszutauschen.
In der Regel handelt es sich dabei um Hardware, es kann aber auch Software sein, wie das loopback Interface.
Das Network-Interface ist für das Senden und Empfangen von Daten zuständig, ausgehend vom Network-Subsystem des Kernels. Es weiß nicht, wie die Transaktionen auf die übertragenen Pakete gemappt werden. Es ist vollkommen protokollunabhängig. Es geht also hauptsächlich darum, die Hardware anzukoppeln. Das Kommunikationsprotokoll wird von höheren Schichten abgebildet.
Telnet und FTP übertragen beide über das gleiche Gerät; das wiederum sieht nur die einzelnen Datenpakete, nicht die einzelnen Datenströme.
Da Netzwerk-Geräte nicht datenstromorientiert arbeiten, ist es schwierig, ein Network-Interface auf einen Knoten im Dateisystem zu mappen. Unter Unix wird der Zugang zu einem solchen Interface dadurch gewährleistet, daß sie einen einmaligen Namen (wie eth0) zugewiesen bekommen, der allerdings keinen entsprechenden Eintrag im Dateisystem bekommt.
Die Kommunikation zwischen Kernel und Netzwerkgeräten unterscheidet sich völlig von der mit character und block devices. Statt read und write werden Funktionen aufgerufen, die sich auf Paketübertragung beziehen.


Unterschiede zu Character- und Blockorientierten Gerätetreibern

  1. Netzwerktreiber benutzen statt struct file_operations die Struktur struct net_device.
  2. Es erfolgt kein Eintrag als Gerätedatei im Filesystem (s.o.).
  3. Der Aufruf erfolgt durch die oberen Schichten des Kommunikationsprotokolls, z.B. TCP/IP.
  4. Der Empfang von Datenpaketen erfolgt asynchron und interruptgesteuert. Applikationen spielen keine Rolle. Es gibt im struct keinen Funktionspointer für das Lesen oder Empfangen von Paketen. Der Netzwerktreiber startet mit seiner ISR eine Empfangsroutine, die dafür sorgt, dass die Daten, nach dem Abholen von der Hardware, von einer Systemfunktion weiter bearbeitet werden.


Programmierung

Wie die anderen Treiber auch werden die Treibermodule mit init_module und cleanup_module registriert und entregistriert.
Die Netzwerkgeräte werden mittels int register_netdev(struct net_device *dev); bzw. void unregister_netdev(struct net_device *dev); an- und abgemeldet. Netzwerktreiber benötigen keine Major- und Minor-Nummern, sondern fügen eine Datenstruktur für jedes neue Interface in eine globale Liste von Netzwerkgeräten ein. Jedes Interface wird durch ein struct net_device beschrieben. Die Struktur beschreiben wir hier nicht, da sie sehr groß ist. Wer Interesse hat, kann sie sich in <linux/netdevices.h> anschauen.
Die Überprüfung des Devices sollte in der init-Funktion erfolgen. I/O-Ports und Interrupt Lines sollten jetzt noch nicht registriert werden, sondern erst, wenn das Device geöffnet wird. Das gilt insbesondere, wenn Interrupt Lines mit anderen Devices geteilt werden, um nicht jedes Mal aufgerufen zu werden, wenn ein anderes Device eine IRQ Line triggert.
Die Initialisierungsroutine sollte die dev-Struktur füllen, was immer zur Laufzeit geschieht. Bei char und block devices werden die Strukturen zur Compilezeit gefüllt.

Insbesondere muß in dieser Struktur das Element init mit der Adresse der probe-Funktion belegt werden. Diese Funktion wird während der Abarbeitung von register_netdev vom Kernel aufgerufen. Die probe-Funktion hat die Aufgabe, die eigentliche Hardwareerkennung durchzuführen. Außerdem werden in dieser Funktion - falls noch nicht geschehen - die Funktionspointer der übrigen Treiberfunktionen (z.B. open, close) in die Struktur struct net_device eingetragen. Da die Struktur ebenso noch protokollspezifische Felder enthält, die initialisiert werden müssen, bietet der Betriebssystemkern Funktionen dafür an. Im Falle einer Ethernet-Karte wird beispielsweise die Funktion ether_setup aufgerufen.
   ether_setup(dev);/*assign some of the fields */
   dev->open =my_open;
   dev->stop =my_release;
   dev->set_config =my_config;
   dev->hard_start_xmit =my_tx;
   dev->do_ioctl =my_ioctl;
   dev->get_stats =my_stats;
   dev->rebuild_header =my_rebuild_header;
   dev->hard_header =my_header;
   #ifdef HAVE_TX_TIMEOUT
     dev->tx_timeout =my_tx_timeout;  /*Transmission Timeouts
     dev->watchdog_timeo =timeout;
   #endif
  /*keep the default flags,just add NOARP */
  dev->flags |=IFF_NOARP;  /*ARP (Address Resolution Protocol) kann nicht benutzt werden
  dev->hard_header_cache =NULL;/*Disable caching */
  SET_MODULE_OWNER(dev);
Die Treiberfunktionen sind die folgenden:

int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev);
int (*hard_start_xmit)(struct sk_buff *skb,struct net_device *dev);
int (*hard_header)(struct sk_buff *skb,struct net_device *dev,unsigned short type,void *daddr,void *saddr, unsigned len);
int (*rebuild_header)(struct sk_buff *skb);
void (*tx_timeout)(struct net_device *dev);
struct net_device_stats *(*get_stats)(struct net_device *dev);
int (*set_config)(struct net_device *dev,struct ifmap *map);
Weitere Funktionen sind optional.


Änderungen im neuen Kernel

Es gibt viele neue Treiber, bug fixes, und existierende Treiber haben mehr Funktionalität erhalten.

Bis Linux 2.2 wurden alle Prozesse, die auf ein Ereignis vom Network Socket warteten, bei Aktivitäten aufgeweckt. Dieser Effekt ist unter Linux 2.4 behoben.

Die Network-Schicht wurde total überarbeitet, ebenso wie die Firewall und das IP-Masquerading.
Das Subsystem wurde in zwei Teile gespalten: eine Paketfilterschicht und eine Network Address Translation-Schicht (NAT).
Explicit Congestion Notification (ECN) erlaubt Routern, eine Linux box zu benachrichtigen, wenn eine Route überfüllt ist. Linux drosselt daraufhin die Geschwindigkeit, mit der Pakete gesendet werden.
Für Enterprise-Level-User werden jetzt DECNet- und ARCNet-Protokolle und Hardware (teilweise) unterstützt.
Für den Desktop-User wurde PPP überarbeitet und verbessert.


... [ Seminar Linux und Apache] ... [ Thema Gerätetreiber unter Linux 2.4] ... [ nach oben ] ... [ Weitere Treiberklassen ] ...