J'essaie de configurer le délai d'expiration ARP. Je pense que je devrais définir /proc/sys/net/ipv4/neigh/default/base_reachable_time_ms
au délai souhaité. Mais même si je l'ai défini à 30000 ms (30 secondes), il faut toujours près de 10 minutes pour qu'une entrée soit supprimée du cache ARP. Après avoir lu quelques articles, je constate qu'il y a quelques autres paramètres qui affectent le délai:
/proc/sys/net/ipv4/neigh/default/gc_interval
/proc/sys/net/ipv4/neigh/default/gc_stale_time
/proc/sys/net/ipv4/route/gc_interval
/proc/sys/net/ipv4/route/gc_timeout
Je ne sais pas quoi programmer pour ceux-ci. Le gc_timeout
par défaut à 5 minutes sous Linux. J'ai changé cela en 30 secondes, mais je ne vois toujours pas l'entrée supprimée dans base_reachable_time/2
ou 3*base_reachable_time/2
.
Comment puis-je définir le délai d'expiration du cache ARP?
Le cache voisin dans le noyau Linux n'est pas aussi simple qu'on pourrait le penser. Je vais essayer d'expliquer certaines des bizarreries avec ça.
Il existe des différences subtiles entre une entrée de cache voisine qui tombe complètement du cache ou qui est simplement marquée comme périmée/non valide. À un moment donné entre base_reachable_time /2 et 3 * base_reachable_time /2, l'entrée sera toujours dans le cache, mais elle sera marquée avec un état STALE. Vous devriez être en mesure d'afficher l'état avec "show voisin ip -s",
pherricoxide@midigaurd:~$ ip -s neighbor list
192.168.42.1 dev eth0 lladdr 00:25:90:7d:7e:cd ref 2 used 184/184/139 probes 4 STALE
192.168.10.2 dev eth0 lladdr 00:1c:23:cf:0b:6a ref 3 used 33/28/0 probes 1 REACHABLE
192.168.10.1 dev eth0 lladdr 00:17:c5:d8:90:a4 ref 219 used 275/4/121 probes 1 REACHABLE
Lorsque dans l'état STALE comme indiqué ci-dessus, si je ping 192.168.42.1, il enverra le paquet à 00: 25: 90: 7d: 7e: cd immédiatement. Une seconde plus tard, il enverra généralement une demande ARP pour qui a 192.168.42.1 afin de mettre à jour son cache dans un état REACHABLE. MAIS, pour rendre les choses plus confuses, le noyau changera parfois les valeurs de délai d'attente en fonction des commentaires positifs des protocoles de niveau supérieur. Cela signifie que si je envoie une requête ping à 192.168.42.1 et qu'il répond, alors le noyau ne prendra pas la peine d'envoyer une demande ARP car il suppose que le pong signifiait que son entrée de cache ARP est valide. Si l'entrée est à l'état STALE, elle sera également mise à jour par les réponses ARP non sollicitées qu'il se trouve.
Désormais, dans la majorité des cas, l'entrée étant à l'état STALE est tout ce dont vous avez besoin. Pourquoi avez-vous besoin que l'entrée soit supprimée de la cache entièrement? Le noyau fait beaucoup d'efforts pour ne pas surcharger la mémoire en changeant simplement l'état des entrées du cache au lieu de les supprimer et de les ajouter en permanence au cache.
Si vous insistez vraiment sur le fait que non seulement il sera marqué comme STALE, mais qu'il sera en fait supprimé de la table de hachage utilisée par le cache voisin, vous devez vous méfier de quelques choses. Premièrement, si l'entrée n'a pas été utilisée et est périmée pendant gc_stale_time secondes, elle devrait pouvoir être supprimée. Si gc_stale_time a réussi et marqué l'entrée comme acceptable pour être supprimée, elle sera supprimée lorsque le garbage collector s'exécute (généralement après gc_interval secondes).
Maintenant, le problème est que l'entrée de voisin ne sera pas supprimée si elle est référencée . La principale chose avec laquelle vous allez avoir des problèmes est la référence de la table de routage ipv4 . Il y a beaucoup de choses compliquées de collecte de déchets, mais la chose importante à noter est que le garbage collector pour le cache de route expire uniquement les entrées toutes les 5 minutes (/proc/sys/net/ipv4/route/gc_timeout secondes) sur de nombreux noyaux. Cela signifie que l'entrée voisine devra être marquée comme périmée (peut-être 30 secondes, selon base_reachable_time ), puis 5 minutes devront s'écouler avant le le cache d'itinéraire arrête de référencer l'entrée (si vous êtes chanceux), suivi d'une combinaison de gc_stale_time et gc_interval passant avant qu'il ne soit réellement nettoyé (donc, globalement, quelque part entre 5 et 10 minutes passeront).
Résumé: vous pouvez essayer de diminuer /proc/sys/net/ipv4/route/gc_timeout à une valeur plus courte, mais il y a beaucoup de variables et c'est difficile de les contrôler tous. Il y a beaucoup d'efforts à faire pour que les choses fonctionnent bien en ne supprimant pas les entrées dans le cache trop tôt (mais en les marquant simplement comme STALE ou même FAILED).
ip link set arp off dev eth0
ip link set arp on dev eth0
Le moyen le plus simple de nettoyer complètement le cache arp est de baisser puis de relancer l'interface. De toute évidence, cela a beaucoup plus d'implications, par exemple, la possibilité de rompre les connexions en cours TCP, être inaccessible pendant un certain temps, etc. Mais cela semble être le seul moyen de vraiment supprimer une entrée du cache arp dans les derniers noyaux :(