Linux a quelques particularités qui le distinguent d'autre SE. Ces particularités incluent:
Les points 4 et 5 donnent une énorme flexibilité aux administrateurs système sur la configuration système du Mode Utilisateur leur permettant de résoudre également des erreurs de noyau critiques ou des problèmes spécifiques sans relancer la machine. Par exemple, si vous devez changer quelque chose sur un gros serveur et vous ne voulez pas faire une réinitialisation, vous pourriez préparer le noyau à dialoguer avec un module, que vous écrirez.
Linux n'utilise pas la segmentation pour distinguer les Tâches les unes des autres; il utilise la pagination. (seulement 2 segments sont utilisés pour tous les Tâches, CODE et DATA/stack)
Nous pouvons également dire qu'un défaut de page interTask ne se produit jamais, parce que chaque Tâche utilise un ensemble de Tables de Page différents pour chaque Tâche. Il y a quelques cas où des Tâches différentes pointent vers les mêmes Tables de page, comme les bibliothèques partagées: c'est nécessaire pour réduire l'utilisation de la mémoire; rappelez-vous que les bibliothèques partagées sont seulement du CODE parce que toutes les données sont stockées dans la pile actuelle de la Tâche.
Sous le noyau Linux seulement 4 segments existent:
[ la syntaxe est ''But [Segment]'']
Sous architecture Intel, les registres de segment utilisés sont:
Ainsi, chaque Tâche utilise 0x23 pour le code et le 0x2b pour données/pile
Sous Linux 3 niveaux des pages sont utilisés, selon l'architecture. Sous Intel seulement 2 niveaux sont supportés. Linux supporte aussi la Copie sur mécanismes Ecriture (voir Chap.10 pour plus d'information).
La réponse est très très simple: les conflits d'adresse interTask ne peuvent pas exister parce qu'ils sont impossibles. Le traçage linéaire -> physique est fait par "Pagination", ainsi il a juste besoin d'assigner les pages physiques de manière univoque.
Le numéro d'Assignement de page est un processus dynamique. Nous avons besoin d'une seule page quand une Tâche le demande, ainsi nous la choisissons dans les pages libres de manière ordonnée. Quand nous voulons libérer la page, nous devons seulement l'ajouter à la liste des pages libres.
Les pages noyau ont un problème: elles peuvent être assignées de façon dynamique mais nous ne pouvons pas avoir de garantie qu'elles sont dans une zone allouée continue, parce que l'espace linéaire du noyau est équivalent à l'espace physique du noyau.
Pour le Segment Code il n'y a pas de problème. Le code de démarrage est assigné lors du démarrage (aussi nous avons une quantité fixe de mémoire à assigner), et sur les modules nous devons seulement allouer une zone mémoire qui pourrait contenir le code du module.
Le vrai problème est le segment de pile parce que chaque Tâche utilise des pages de pile noyau. Les segments de pile doivent être contigus (selon la définition de pile), ainsi nous devons établir une limite maximum pour la dimension de pile de chaque Tâche. Si nous dépassons cette limite, de mauvaises choses se produisent. Nous recouvrons des structures de données de processus en Mode Noyau.
La structure du noyau nous aide, parce que les fonctions du noyau ne sont jamais:
Une fois que nous connaissons N, et que nous connaissons la moyenne des variables statiques pour toutes les fonctions noyau, nous pouvons estimer une limite de pile.
Si vous voulez tester le problème, vous pouvez créer un module avec une fonction qui s'appelle plusieurs fois. Après un nombre fixé de fois, le module du noyau abandonnera en raison d'une faute du gestionnaire de page d'exception (typiquement écrire à une page lecture-seule).
Quand un IRQ arrive, la commutation de Tâche est reportée à plus tard pour obtenir de meilleures performances. Quelques travaux de Tâche (qui pourrait devoir être fait juste aprés l'IRQ et qui pourraient prendre beaucoup de processeur dans le temps d'interruption, comme accumuler un paquet de TCP/IP) sont mis en queue (alignés) et seront faits au temps programmé (une fois qu'un temps-tranche (time-slice) finit).
Dans les noyaux récents (2.4.x) les mécanismes de softirq sont passés à un kernel_thread (fil de noyau): ''ksoftirqd_CPUn''. n représente le nombre processeur exécutant le kernel_thread (dans système monoprocessor ''ksoftirqd_CPU0'' utilise PID 3).
Le ''cpu_raise_softirq'' est une routine qui réveille le fil du noyau ''ksoftirqd_CPU0'', pour le laisser contrôler le travail mis en file d'attente.
|cpu_raise_softirq |__cpu_raise_softirq |wakeup_softirqd |wake_up_process
la routine ''__de cpu_raise_softirq__'' placera le bon octet dans le vecteur décrivant le softirq en suspens.
''wakeup_softirq'' utilise le ''wakeup_process'' pour réveiller le fil du noyau ''ksoftirqd_CPU0''.
A FAIRE: décrire les structures de données impliquées dans le mécanisme de softirq.
Quand le fil noyau ''ksoftirqd_CPU0'' a été réveillé, il exécute les travaux de la file.
Le code de ''ksoftirqd_CPU0'' est (boucle principale sans fin):
for (;;) { if (!softirq_pending(cpu)) schedule(); __set_current_state(TASK_RUNNING); while (softirq_pending(cpu)) { do_softirq(); if (current->need_resched) schedule } __set_current_state(TASK_INTERRUPTIBLE) }
Quoique Linux soit un OS monolithique, quelques ''fils du noyau'' existent pour faire le ménage.
Ces Tâches n'utilisent pas la mémoire Utilisateur; elles partagent la mémoire NOYAU. Elles opèrent également avec le privilège le plus élevé (ANNEAU 0 sur une architecture i386) comme tout autre bout de code Mode Noyau.
Des fils du noyau sont créés par la fonction ''kernel_thread [ arch/i386/kernel/process ]'', qui appelle un appel système ''clone'' [ arch/i386/kernel/process.c ] de l'assembleur (qui est ''une fourche'' comme l'appel système):
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { long retval, d0; __asm__ __volatile__( "movl %%esp,%%esi\n\t" "int $0x80\n\t" /* Linux/i386 system call */ "cmpl %%esp,%%esi\n\t" /* child or parent? */ "je 1f\n\t" /* parent - jump */ /* Load the argument into eax, and push it. That way, it does * not matter whether the called function is compiled with * -mregparm or not. */ "movl %4,%%eax\n\t" "pushl %%eax\n\t" "call *%5\n\t" /* call fn */ "movl %3,%0\n\t" /* exit */ "int $0x80\n" "1:\t" :"=&a" (retval), "=&S" (d0) :"0" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), "b" (flags | CLONE_VM) : "memory"); return retval; }
Une fois appelée, nous avons une nouvelle Tâche (habituellement avec un nombre très bas de PID, comme 2.3, etc...) attendant une ressource très lente, comme un événement échange ou usb. Une ressource très lente est utilisée parce qu'autrement nous aurions une commutation de Tâche coûteuse (overhead).
Au-dessous une liste de la plupart des fils du noyau courants (avec ''ps x''):
PID COMMAND 1 init 2 keventd 3 kswapd 4 kreclaimd 5 bdflush 6 kupdated 7 kacpid 67 khubd
Le fil noyau ''init'' est le premier processus créé, au démarrage. Il appellera toutes autres Tâches Mode Utilisateur (à partir du fichier /etc/inittab) comme les démons console, les démons tty et les démons réseau (''rc'' scripts).
''kswapd'' est créé par ''clone() [arch/i386/kernel/process.c]''
Routines d'initialisation:
|do_initcalls |kswapd_init |kernel_thread |syscall fork (in assembler)
do_initcalls [init/main.c]
kswapd_init [mm/vmscan.c]
kernel_thread [arch/i386/kernel/process.c]
Les modules du noyau Linux sont des bouts de code (exemples: fs, net, et pilotes hw) fonctionnant en Mode Noyau que vous pouvez ajouter à chaud.
Le coeur de Linux ne peut pas être modularisé: programmation et gestion d'interruption ou noyau du réseau, etc...
Sous "/lib/modules/KERNEL_VERSION/" vous pouvez trouver tous les modules installés sur votre système.
Pour charger un module, tapez ce qui suit:
insmod MODULE_NAME parameters exemple: insmod ne io=0x300 irq=9
NOTE: Vous pouvez utiliser modprobe à la place d'insmod si vous voulez que le noyau recherche automatiquement certains paramètres (par exemple en utilisant le pilote de PCI, ou si vous avez indiqué un paramètre dans le fichier /etc/conf.modules).
Pour décharger un module, tapez ce qui suit:
rmmod MODULE_NAME
Un module contient toujours:
Si ces fonctions ne sont pas dans le module, vous devez ajouter 2 macros pour indiquer quelles fonctions agiront en tant qu'init et sortie du module:
NOTE: un module peut "voir" une variable du noyau seulement si elle a été exportée (avec la macro EXPORT_symbol).
// kernel sources side void (*foo_function_pointer)(void *); if (foo_function_pointer) (foo_function_pointer)(parameter); // module side extern void (*foo_function_pointer)(void *); void my_function(void *parameter) { //My code } int init_module() { foo_function_pointer = &my_function; } int cleanup_module() { foo_function_pointer = NULL; }
Cette simple astuce vous permet d'avoir une flexibilité très élevée dans le noyau, parce que ne ferez exécuter la routine "ma_fonction" que quand vous chargerez le module. Cette routine fera tout ce que vous voulez faire: par exemple le module ''rshaper'', qui commande le trafic d'entrée de bande passante du réseau, fonctionne dans ce cas de figure.
Notez que le mécanisme entier de module est possible grâce à quelques variables globales exportées vers les modules, telles qu'une liste entête (vous permettant d'étendre la liste autant que vous voulez). Les exemples typiques sont fs, pilotes génériques (caractère, bloc, réseau, téléphonie). Vous devez préparer le noyau à accepter votre nouveau module; dans certains cas vous devez créer une infrastructure (comme celle de la téléphonie, créée récemment) pour être aussi standard que possible.
Proc fs (système de fichiers) est situé dans le dossier /proc, qui est un dossier spécial vous permettant de dialoguer directement avec le noyau.
Linux utilise le dossier ''proc'' pour supporter les communications directes du noyau: c'est nécessaire dans plusieurs de cas, par exemple quand vous voulez voir les structures de données de processus principaux ou autoriser le dispositif ''proxy-arp'' pour une interface et pas pour d'autres, vous voulez changer le nombre maximum de fils, ou si vous voulez corriger certains états de bus, comme ISA ou PCI, pour savoir quelles cartes sont installées et quelles adresses E/S et IRQs leur sont assignées.
|-- bus | |-- pci | | |-- 00 | | | |-- 00.0 | | | |-- 01.0 | | | |-- 07.0 | | | |-- 07.1 | | | |-- 07.2 | | | |-- 07.3 | | | |-- 07.4 | | | |-- 07.5 | | | |-- 09.0 | | | |-- 0a.0 | | | `-- 0f.0 | | |-- 01 | | | `-- 00.0 | | `-- devices | `-- usb |-- cmdline |-- cpuinfo |-- devices |-- dma |-- dri | `-- 0 | |-- bufs | |-- clients | |-- mem | |-- name | |-- queues | |-- vm | `-- vma |-- driver |-- execdomains |-- filesystems |-- fs |-- ide | |-- drivers | |-- hda -> ide0/hda | |-- hdc -> ide1/hdc | |-- ide0 | | |-- channel | | |-- config | | |-- hda | | | |-- cache | | | |-- capacity | | | |-- driver | | | |-- geometry | | | |-- identify | | | |-- media | | | |-- model | | | |-- settings | | | |-- smart_thresholds | | | `-- smart_values | | |-- mate | | `-- model | |-- ide1 | | |-- channel | | |-- config | | |-- hdc | | | |-- capacity | | | |-- driver | | | |-- identify | | | |-- media | | | |-- model | | | `-- settings | | |-- mate | | `-- model | `-- via |-- interrupts |-- iomem |-- ioports |-- irq | |-- 0 | |-- 1 | |-- 10 | |-- 11 | |-- 12 | |-- 13 | |-- 14 | |-- 15 | |-- 2 | |-- 3 | |-- 4 | |-- 5 | |-- 6 | |-- 7 | |-- 8 | |-- 9 | `-- prof_cpu_mask |-- kcore |-- kmsg |-- ksyms |-- loadavg |-- locks |-- meminfo |-- misc |-- modules |-- mounts |-- mtrr |-- net | |-- arp | |-- dev | |-- dev_mcast | |-- ip_fwchains | |-- ip_fwnames | |-- ip_masquerade | |-- netlink | |-- netstat | |-- packet | |-- psched | |-- raw | |-- route | |-- rt_acct | |-- rt_cache | |-- rt_cache_stat | |-- snmp | |-- sockstat | |-- softnet_stat | |-- tcp | |-- udp | |-- unix | `-- wireless |-- partitions |-- pci |-- scsi | |-- ide-scsi | | `-- 0 | `-- scsi |-- self -> 2069 |-- slabinfo |-- stat |-- swaps |-- sys | |-- abi | | |-- defhandler_coff | | |-- defhandler_elf | | |-- defhandler_lcall7 | | |-- defhandler_libcso | | |-- fake_utsname | | `-- trace | |-- debug | |-- dev | | |-- cdrom | | | |-- autoclose | | | |-- autoeject | | | |-- check_media | | | |-- debug | | | |-- info | | | `-- lock | | `-- parport | | |-- default | | | |-- spintime | | | `-- timeslice | | `-- parport0 | | |-- autoprobe | | |-- autoprobe0 | | |-- autoprobe1 | | |-- autoprobe2 | | |-- autoprobe3 | | |-- base-addr | | |-- devices | | | |-- active | | | `-- lp | | | `-- timeslice | | |-- dma | | |-- irq | | |-- modes | | `-- spintime | |-- fs | | |-- binfmt_misc | | |-- dentry-state | | |-- dir-notify-enable | | |-- dquot-nr | | |-- file-max | | |-- file-nr | | |-- inode-nr | | |-- inode-state | | |-- jbd-debug | | |-- lease-break-time | | |-- leases-enable | | |-- overflowgid | | `-- overflowuid | |-- kernel | | |-- acct | | |-- cad_pid | | |-- cap-bound | | |-- core_uses_pid | | |-- ctrl-alt-del | | |-- domainname | | |-- hostname | | |-- modprobe | | |-- msgmax | | |-- msgmnb | | |-- msgmni | | |-- osrelease | | |-- ostype | | |-- overflowgid | | |-- overflowuid | | |-- panic | | |-- printk | | |-- random | | | |-- boot_id | | | |-- entropy_avail | | | |-- poolsize | | | |-- read_wakeup_threshold | | | |-- uuid | | | `-- write_wakeup_threshold | | |-- rtsig-max | | |-- rtsig-nr | | |-- sem | | |-- shmall | | |-- shmmax | | |-- shmmni | | |-- sysrq | | |-- tainted | | |-- threads-max | | `-- version | |-- net | | |-- 802 | | |-- core | | | |-- hot_list_length | | | |-- lo_cong | | | |-- message_burst | | | |-- message_cost | | | |-- mod_cong | | | |-- netdev_max_backlog | | | |-- no_cong | | | |-- no_cong_thresh | | | |-- optmem_max | | | |-- rmem_default | | | |-- rmem_max | | | |-- wmem_default | | | `-- wmem_max | | |-- ethernet | | |-- ipv4 | | | |-- conf | | | | |-- all | | | | | |-- accept_redirects | | | | | |-- accept_source_route | | | | | |-- arp_filter | | | | | |-- bootp_relay | | | | | |-- forwarding | | | | | |-- log_martians | | | | | |-- mc_forwarding | | | | | |-- proxy_arp | | | | | |-- rp_filter | | | | | |-- secure_redirects | | | | | |-- send_redirects | | | | | |-- shared_media | | | | | `-- tag | | | | |-- default | | | | | |-- accept_redirects | | | | | |-- accept_source_route | | | | | |-- arp_filter | | | | | |-- bootp_relay | | | | | |-- forwarding | | | | | |-- log_martians | | | | | |-- mc_forwarding | | | | | |-- proxy_arp | | | | | |-- rp_filter | | | | | |-- secure_redirects | | | | | |-- send_redirects | | | | | |-- shared_media | | | | | `-- tag | | | | |-- eth0 | | | | | |-- accept_redirects | | | | | |-- accept_source_route | | | | | |-- arp_filter | | | | | |-- bootp_relay | | | | | |-- forwarding | | | | | |-- log_martians | | | | | |-- mc_forwarding | | | | | |-- proxy_arp | | | | | |-- rp_filter | | | | | |-- secure_redirects | | | | | |-- send_redirects | | | | | |-- shared_media | | | | | `-- tag | | | | |-- eth1 | | | | | |-- accept_redirects | | | | | |-- accept_source_route | | | | | |-- arp_filter | | | | | |-- bootp_relay | | | | | |-- forwarding | | | | | |-- log_martians | | | | | |-- mc_forwarding | | | | | |-- proxy_arp | | | | | |-- rp_filter | | | | | |-- secure_redirects | | | | | |-- send_redirects | | | | | |-- shared_media | | | | | `-- tag | | | | `-- lo | | | | |-- accept_redirects | | | | |-- accept_source_route | | | | |-- arp_filter | | | | |-- bootp_relay | | | | |-- forwarding | | | | |-- log_martians | | | | |-- mc_forwarding | | | | |-- proxy_arp | | | | |-- rp_filter | | | | |-- secure_redirects | | | | |-- send_redirects | | | | |-- shared_media | | | | `-- tag | | | |-- icmp_echo_ignore_all | | | |-- icmp_echo_ignore_broadcasts | | | |-- icmp_ignore_bogus_error_responses | | | |-- icmp_ratelimit | | | |-- icmp_ratemask | | | |-- inet_peer_gc_maxtime | | | |-- inet_peer_gc_mintime | | | |-- inet_peer_maxttl | | | |-- inet_peer_minttl | | | |-- inet_peer_threshold | | | |-- ip_autoconfig | | | |-- ip_conntrack_max | | | |-- ip_default_ttl | | | |-- ip_dynaddr | | | |-- ip_forward | | | |-- ip_local_port_range | | | |-- ip_no_pmtu_disc | | | |-- ip_nonlocal_bind | | | |-- ipfrag_high_thresh | | | |-- ipfrag_low_thresh | | | |-- ipfrag_time | | | |-- neigh | | | | |-- default | | | | | |-- anycast_delay | | | | | |-- app_solicit | | | | | |-- base_reachable_time | | | | | |-- delay_first_probe_time | | | | | |-- gc_interval | | | | | |-- gc_stale_time | | | | | |-- gc_thresh1 | | | | | |-- gc_thresh2 | | | | | |-- gc_thresh3 | | | | | |-- locktime | | | | | |-- mcast_solicit | | | | | |-- proxy_delay | | | | | |-- proxy_qlen | | | | | |-- retrans_time | | | | | |-- ucast_solicit | | | | | `-- unres_qlen | | | | |-- eth0 | | | | | |-- anycast_delay | | | | | |-- app_solicit | | | | | |-- base_reachable_time | | | | | |-- delay_first_probe_time | | | | | |-- gc_stale_time | | | | | |-- locktime | | | | | |-- mcast_solicit | | | | | |-- proxy_delay | | | | | |-- proxy_qlen | | | | | |-- retrans_time | | | | | |-- ucast_solicit | | | | | `-- unres_qlen | | | | |-- eth1 | | | | | |-- anycast_delay | | | | | |-- app_solicit | | | | | |-- base_reachable_time | | | | | |-- delay_first_probe_time | | | | | |-- gc_stale_time | | | | | |-- locktime | | | | | |-- mcast_solicit | | | | | |-- proxy_delay | | | | | |-- proxy_qlen | | | | | |-- retrans_time | | | | | |-- ucast_solicit | | | | | `-- unres_qlen | | | | `-- lo | | | | |-- anycast_delay | | | | |-- app_solicit | | | | |-- base_reachable_time | | | | |-- delay_first_probe_time | | | | |-- gc_stale_time | | | | |-- locktime | | | | |-- mcast_solicit | | | | |-- proxy_delay | | | | |-- proxy_qlen | | | | |-- retrans_time | | | | |-- ucast_solicit | | | | `-- unres_qlen | | | |-- route | | | | |-- error_burst | | | | |-- error_cost | | | | |-- flush | | | | |-- gc_elasticity | | | | |-- gc_interval | | | | |-- gc_min_interval | | | | |-- gc_thresh | | | | |-- gc_timeout | | | | |-- max_delay | | | | |-- max_size | | | | |-- min_adv_mss | | | | |-- min_delay | | | | |-- min_pmtu | | | | |-- mtu_expires | | | | |-- redirect_load | | | | |-- redirect_number | | | | `-- redirect_silence | | | |-- tcp_abort_on_overflow | | | |-- tcp_adv_win_scale | | | |-- tcp_app_win | | | |-- tcp_dsack | | | |-- tcp_ecn | | | |-- tcp_fack | | | |-- tcp_fin_timeout | | | |-- tcp_keepalive_intvl | | | |-- tcp_keepalive_probes | | | |-- tcp_keepalive_time | | | |-- tcp_max_orphans | | | |-- tcp_max_syn_backlog | | | |-- tcp_max_tw_buckets | | | |-- tcp_mem | | | |-- tcp_orphan_retries | | | |-- tcp_reordering | | | |-- tcp_retrans_collapse | | | |-- tcp_retries1 | | | |-- tcp_retries2 | | | |-- tcp_rfc1337 | | | |-- tcp_rmem | | | |-- tcp_sack | | | |-- tcp_stdurg | | | |-- tcp_syn_retries | | | |-- tcp_synack_retries | | | |-- tcp_syncookies | | | |-- tcp_timestamps | | | |-- tcp_tw_recycle | | | |-- tcp_window_scaling | | | `-- tcp_wmem | | `-- unix | | `-- max_dgram_qlen | |-- proc | `-- vm | |-- bdflush | |-- kswapd | |-- max-readahead | |-- min-readahead | |-- overcommit_memory | |-- page-cluster | `-- pagetable_cache |-- sysvipc | |-- msg | |-- sem | `-- shm |-- tty | |-- driver | | `-- serial | |-- drivers | |-- ldisc | `-- ldiscs |-- uptime `-- version
Dans ce dossier il y a aussi les Tâches qui utilisent le PID comme nom de fichier (vous avez accès à toutes les informations sur les Tâches, comme le chemin du fichier binaire, la mémoire utilisée, etc...).
Ce qui est intéressant c'est que non seulement vous pouvez voir les valeurs du noyau (par exemple, voir l'information sur toute Tâche ou sur les options actives du réseau de votre pile TCP/IP) mais vous pouvez aussi en modifier certaines, typiquement ceux qui sont dans le dossier /proc/sys:
/proc/sys/ acpi dev debug fs proc net vm kernel
Suivent des valeurs du noyau très importantes et bien connues, prêtes à être modifiées:
overflowgid overflowuid random threads-max // Nombre maximum de fils, typiquement 16384 sysrq // hachage noyau: vous pouvez voir les valeurs du registre istant (istant) et plus sem msgmnb msgmni msgmax shmmni shmall shmmax rtsig-max rtsig-nr modprobe // emplacement fichier modprobe printk ctrl-alt-del cap-bound panic domainname // nom de domaine de votre poste Linux hostname // nom d'hôte de votre poste Linux version // informations sur la date de compilation de votre noyau osrelease // version du noyau (i.e. 2.4.5) ostype // Linux!
Il peut être considéré comme le sous-dossier le plus utile de proc. Il vous parmet de changer des paramètres très importants de la configuration réseau de votre noyau.
core ipv4 ipv6 unix ethernet 802
La liste suivante est la configuration générale du réseau, comme netdev_max_backlog" (typiquement 300), la longueur de tous les paquets réseau. Cette valeur peut limiter la bande passante du réseau quand il reçoit des paquets. Linux doit attendre pour programmer le temps de vider les tampons (du aux mécanismes de la moitié d'en bas), envirn 1000/HZ ms (Listed below are general net settings, like "netdev_max_backlog" (typically 300), the length of all your network packets. This value can limit your network bandwidth when receiving packets, Linux has to wait up to scheduling time to flush buffers (due to bottom half mechanism), about 1000/HZ ms)
300 * 100 = 30 000 packets HZ(Timeslice freq) packets/s 30 000 * 1000 = 30 M packets average (Bytes/packet) throughput Bytes/s
Si vous voulez un plus gros débit, vous pouvez augmenter netdev_max_backlog,en tapant:
echo 4000 > /proc/sys/net/core/netdev_max_backlog
Note: Attention à certaines valeurs HZ: sous certaines architectures (comme alpha ou arm-tbox) c'est 1000, aussi vous pouvez avoir un débit moyen de 300 Mo/s.
"ip_forward", active ou désactive la réexpédition ou transmission ip (ip forwarding) dans votre poste Linux. C'est une configuration générique pour tous les périphériques, que vous pouvez spécifier pour chaque périphérique que vous choisissez.
Je pense que c'est l'entrée de /proc la plus utile, parce qu'elle permet de modifier la configuration réseau pour supporter les réseaux sans fils (voir Wireless-HOWTO pour plus d'informations, ou le guide pratique officiel Wireless-HOWTO).
Quelques exemples où vous pouvez utiliser ces réglages: