kernel: Neighbour table overflow

Quem mantém um firewall, proxy ou qualquer outro sistema que receba muitas conexões simultâneas deve ter se deparado com a mensagem “kernel: Neighbour table overflow“. Trata-se de um alerta sobre o estouro do limite da tabela ARP e as conesquencias disto pode ser a lentidão ou até mesmo perda de pacotes tornando as conexões de rede com esta máquina instável. O problema é resolvido facilmente. Veja como.

Os mais desesperados podem resolver o problema simplesmente fazendo assim:

# echo 16384 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
# echo 32768 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
# echo 65535 > /proc/sys/net/ipv4/neigh/default/gc_thresh3

Obviamente isso resolve o problema da grande maioria das pessoas que cehgarão a este texto por uma busca no Google, mas esta não é uma solução definitiva e nem é muito sensato fazer algo sem saber exatamente o que está sendo feito.

Entendendo o problema

A tabela ARP do Kernel do Linux tem um tamanho máximo que está definido dentro do arquivo /proc/sys/net/ipv4/neigh/default/gc_thresh3 e como era de se esperar se tem um tamanho máximo, ao ultrapassarmos este limite ela vai estourar.

E é isso que acontece quando vemos aquela mensagem nos logs dos nossos servidores. Quando a mensagem é exibida saiba que você já está com problemas e provavelmente você notará dificuldades para manter uma conexão com o servidor.

A solução vem com o aumento do limite desta tabela, mas não é muito legal você colocar a tabela no máximo. Existem outros parâmetros que você deve conhecer e que podem ajudá-lo a otimizar seu sistema.

As configurações da tabela ARP

Periodicamente o cache é verificado e as entradas mais antiga são removidas. O tempo em que isto ocorre é dado pelo intervalo definido em /proc/sys/net/ipv4/neigh/default/gc_interval que por padrão é de 30s.

Ou seja, a cada 30s o sistema analisa a tabela e chama o coletor de lixo (garbage colector) de acordo com as configurações dos outros três arquivos:

O arquivo /proc/sys/net/ipv4/neigh/default/gc_thresh1 define a quantidade mínima de endereços ARP que devem estar na tabela para que o coletor de lixo seja disparado.

Caso a tabela tenha menos endereços que o definido em gc_thresh1, o coletor não será evocado.

O arquivo /proc/sys/net/ipv4/neigh/default/gc_thresh2 define a quantidade máxima de endereços ARP que a tabela deverá suportar antes de chamar o coletor de lixo.

Caso a tabela tenha mais endereços que o definido em gc_thresh2, o coletor recolherá todos os endereços que estiverem lá por mais de 5s.

O arquivo /proc/sys/net/ipv4/neigh/default/gc_thresh3 define a quantidade máxima de endereços ARP que a tabela deverá suportar como um todo.

Caso a tabela tenha mais endereços que o definido em gc_thresh3, o coletor será executado imediatamente, removendo as entradas mais antigas e mantendo-a dentro do limite estipulado.

Configurando a tabela

Para saber quantos endereços temos na tabela basta usar o comando arp -n ou para obter apenas a quantidade use:

arp -an|wc -l

Isto envia a saída do comando arp (sem cabeçalhos) para o comando wc que conta o número de linhas retornadas.

Para sabermos o quanto a nossa tabela suporta bastaria olhar os três arquivos já citados. Uma dica para ve-los simultaneamente seria usando o comando grep assim:

grep . /proc/sys/net/ipv4/neigh/default/gc_thresh*

Claro que você poderia usar o cat para listar os arquivos individualmente, mas desta forma nós matamos três coelhos com uma cajadada só. A saída deverá ser algo assim:

/proc/sys/net/ipv4/neigh/default/gc_thresh1:128
/proc/sys/net/ipv4/neigh/default/gc_thresh2:512
/proc/sys/net/ipv4/neigh/default/gc_thresh3:1024

Existem três foras de alterarmos estes valores, sendo uma permanente e as outras duas enquanto o sistema não é reiniciado.

Uma já foi dada lá no início do artigo e só é válida até reiniciarmos o servidor. A segunda consiste em usar o comando sysctl que serve para configurar parâmetros do kernel em runtime.

# sysctl -w net.ipv4.neigh.default.gc_thresh3=2048
# sysctl -w net.ipv4.neigh.default.gc_thresh2=1024
# sysctl -w net.ipv4.neigh.default.gc_thresh1=512

Assim como da maneira anterior, este comando vai alterar os valores instantaneamente e permanecerá assim até que o sistema seja reiniciado.

Para que você mantenha os valores de forma permanente é preciso editar o arquivo de configuração do sysctl e definir estes valores lá.

Usando o seu editor de textos preferido edite o arquivo /etc/sysctl.conf e acrescene as seguintes linhas de acordo com a sua necessidade:

net.ipv4.neigh.default.gc_thresh3 = 2048
net.ipv4.neigh.default.gc_thresh2 = 1024
net.ipv4.neigh.default.gc_thresh1 = 512

Feito isso você pode recarregar as configurações para se certificar de que está tudo ok digitando o comando:

sysctl -p

Se nada der errado, então o trabalho está concluído.

Referências

Tobias Lachmann. Neighbour table overflow. Jan. 2010. Disponível em <http://blog.lachmann.org/2010/01/neighbour-table-overflow/>

Linuxman. Neighbour table overflow. Jan. 2010. Disponível em <http://linuxman.wikispaces.com/Neighbour+table+overflow>

Carlos Affonso Henriques. Eliminando o Neighbour table overflow. Mai. 2006. Disponível em <http://www.vivaolinux.com.br/dica/Eliminando-o-Neighbour-table-overflow>

Die.net. Manpage systcl. Disponível em <http://linux.die.net/man/8/sysctl>

Die.net. Manpage arp. Disponível em <http://linux.die.net/man/7/arp>

Um comentário em “kernel: Neighbour table overflow”

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.