El caché vecino en el kernel de Linux no es tan simple.
Hay diferencias sutiles entre una entrada de caché vecina que en realidad se sale del caché por completo o simplemente se marca como obsoleta/no válida. En algún momento entre base_reachable_time /2 y 3* base_reachable_time /2, la entrada seguirá estando en la memoria caché, pero se marcará con un estado OBSERVADO. Debería poder ver el estado con "ip -s vecino show".
Cuando esté en el estado STALE como se muestra arriba, si hago ping a 10.64.42.121, enviará el paquete a b8:20:00:00:00:00 de inmediato. Aproximadamente un segundo después, generalmente enviará una solicitud ARP para quien tenga 10.64.42.121 para actualizar su caché a un estado REACHABLE. PERO, para hacer las cosas más confusas, el kernel a veces cambiará los valores de tiempo de espera en función de los comentarios positivos de los protocolos de nivel superior. Lo que esto significa es que si hago ping a 10.64.42.121 y responde, es posible que el kernel no se moleste en enviar una solicitud ARP porque asume que el pong significa que su entrada de caché ARP es válida. Si la entrada está en estado OBSERVADO, también se actualizará con las respuestas ARP no solicitadas que vea.
Ahora, en la mayoría de los casos, la entrada en estado OBSERVADO es todo lo que necesita para preocuparse. ¿Por qué necesita que la entrada se elimine por completo del caché? El núcleo hace un gran esfuerzo para no sobrecargar la memoria simplemente cambiando el estado de las entradas de la memoria caché en lugar de eliminarlas y agregarlas a la memoria caché todo el tiempo.
Si realmente insiste en que no solo se marcará como OBSERVADO, sino que en realidad se eliminará del mapa hash utilizado por el caché vecino, debe tener cuidado con algunas cosas. Primero, si la entrada no se ha utilizado y está obsoleta durante gc_stale_time segundos, debería ser elegible para ser eliminado. Si gc_stale_time pasó y marcó la entrada como aceptable para ser eliminada, se eliminará cuando se ejecute el recolector de basura (generalmente después de gc_interval segundos).
Ahora el problema es que la entrada de vecino no se eliminará si se hace referencia a ella . Lo principal con lo que tendrá problemas es la referencia de la tabla de enrutamiento ipv4. Hay muchas cosas complicadas de recolección de basura, pero lo importante a tener en cuenta es que el recolector de basura para el caché de ruta solo caduca las entradas cada 5 minutos (/proc/sys/net/ipv4/route/gc_timeout segundos) en muchos núcleos. Esto significa que la entrada del vecino deberá marcarse como obsoleta (quizás 30 segundos, según el base_reachable_time). ), luego tendrán que pasar 5 minutos antes de que el caché de ruta deje de hacer referencia a la entrada (si tiene suerte), seguido de alguna combinación de gc_stale_time y gc_interval pasando antes de que realmente se limpie (por lo tanto, en general, pasarán entre 5 y 10 minutos).
Resumen:puede intentar disminuir /proc/sys/net/ipv4/route/gc_timeout a un valor más corto, pero hay muchas variables y es difícil controlarlas todas. Se ha puesto mucho esfuerzo en hacer que las cosas funcionen bien al no eliminar las entradas en el caché demasiado pronto (sino simplemente marcarlas como OBSERVADAS o incluso FALLIDAS).
gc_stale_time
es el parámetro correcto para modificar para desalojar las entradas OBSERVADAS de la tabla ARP. Pero hay más:
La recolección de basura ARP se ejecuta en el neigh_periodic_work
periódico función. El intervalo se puede ajustar a través de la variable /proc/sys gc_interval
.
Luego verificará que haya al menos gc_thresh1
entradas en la tabla ARP. Esto evitará consumir ciclos de CPU adicionales si la tabla es demasiado pequeña para ver algún beneficio real en términos de memoria.
En tu caso, sospecho gc_thresh1
es la variable que querrá modificar. bajarlo obligará al GC a funcionar con más frecuencia. Sin embargo, esto puede tener un impacto negativo en el rendimiento según el intervalo de ejecución.
Nota:gc_thresh3
es un umbral duro. La tabla nunca mantendrá más entradas que este valor. Ajústalo con cuidado.