Quando as entradas ARP STALE se tornam FALHAS quando nunca usadas?

5
root@openwrt:~# ip -s -s -4 neigh show dev lan
10.64.42.121 lladdr b8:20:00:00:00:00 used 6387/6341/6313 probes 1 STALE
10.64.42.157 lladdr b8:20:00:00:00:00 used 24/813/19 probes 1 STALE
10.64.42.12  used 29066/30229/29063 probes 6 FAILED
10.64.42.1 lladdr e8:00:00:00:00:00 ref 1 used 10/5/5 probes 1 REACHABLE


root@openwrt:~# cat /proc/sys/net/ipv4/neigh/default/gc_interval 
30

root@openwrt:~# cat /proc/sys/net/ipv4/neigh/default/gc_stale_time
60

root@openwrt:~# cat /proc/sys/net/ipv4/neigh/lan/gc_stale_time
60

Um host na lan (b8: 20: 00: 00: 00: 00) tinha o endereço IP 10.64.42.121. Este IP agora é inválido e o IP desse mesmo host é 10.64.42.157 (nova concessão de DHCP).

Eu tento descobrir quando a entrada do cache do arp antigo muda de estado para FAILED ( fornecendo que ninguém tente entrar em contato com o IP ).

A última vez que a entrada foi confirmada é 6341s atrás (1h45 atrás). Isso é maior que 60s. Por que essa entrada ainda está no estado STALE e quando ela será alterada para o estado FAILED (ou será excluída) (se ninguém tentar usar a entrada)?

    
por Fox 22.03.2016 / 18:06

4 respostas

2

gc_stale_time é o parâmetro correto a ser usado para despejar entradas STALE da tabela ARP. Mas tem mais:

A coleta de lixo do ARP é executada no neigh_periodic_work . O intervalo pode ser ajustado via variável / proc / sys gc_interval .

Em seguida, ele verificará se há pelo menos gc_thresh1 entradas na tabela ARP . Isso evitará consumir ciclos extras da CPU se a tabela for pequena demais para ver qualquer benefício real em termos de memória.

No seu caso, eu suspeito que gc_thresh1 é a variável que você vai querer ajustar. abaixar isso forçará o GC a ser executado com mais freqüência. Isso pode ter um impacto negativo no desempenho, dependendo do intervalo de execução.

Nota: gc_thresh3 é um limite rígido. A tabela nunca manterá mais entradas do que esse valor. Ajuste com cuidado.

    
por 01.06.2016 / 14:00
6

O cache vizinho no kernel do Linux não é tão simples.

Existem diferenças sutis entre uma entrada de cache do vizinho que está caindo do cache ou está sendo marcada como obsoleta / inválida. Em algum ponto entre base_reachable_time / 2 e 3 * base_reachable_time / 2, a entrada ainda estará no cache, mas será marcada com um estado de STALE. Você deve ser capaz de ver o estado com "ip -s vizinho show".

Quando no estado STALE, como mostrado acima, se eu fizer ping em 10.64.42.121, ele enviará o pacote para b8: 20: 00: 00: 00: 00 imediatamente. Um segundo ou mais tarde, ele geralmente enviará uma solicitação ARP para quem tem 10.64.42.121 para atualizar seu cache de volta para um estado REACHABLE. MAS, para tornar as coisas mais confusas, o kernel às vezes altera os valores de tempo limite com base no feedback positivo dos protocolos de nível mais alto. O que isto significa é que, se eu fizer ping em 10.64.42.121 e ele responder, o kernel pode não se incomodar em enviar um pedido ARP, porque ele assume que o pong significou que a entrada de cache do ARP é válida. Se a entrada estiver no estado STALE, ela também será atualizada por respostas não solicitadas do ARP que ela veja.

Agora, para a maioria dos casos, a entrada no estado STALE é tudo que você precisa se preocupar. Por que você precisa que a entrada seja removida do cache completamente? O kernel faz um grande esforço para não debater a memória apenas alterando o estado das entradas de cache, em vez de realmente removê-las e adicioná-las ao cache o tempo todo.

Se você realmente insistir que ele não só será marcado como STALE, mas será realmente removido do hashmap usado pelo cache vizinho, você deve tomar cuidado com algumas coisas. Primeiro, se a entrada não tiver sido usada e estiver obsoleta por gc_stale_time segundos, ela deve estar qualificada para remoção. Se gc_stale_time passar e marcar a entrada como ok para ser removida, ela será removida quando o coletor de lixo for executado (geralmente após gc_interval segundos).

Agora, o problema é que a entrada vizinha não será excluída se estiver sendo referenciada . A principal coisa que você vai ter problemas é a referência do ipv4 tabela de roteamento . Há muita coisa complicada na coleta de lixo, mas o importante a ser observado é que o coletor de lixo para o cache de rota expira as entradas a cada 5 minutos ( / proc / sys / net / ipv4 / route / gc_timeout segundos) em muitos kernels. Isto significa que a entrada vizinha terá que ser marcada como obsoleta (talvez 30 segundos, dependendo de base_reachable_time ), então 5 minutos terão que passar antes que o cache de rota pare de referenciar a entrada (se você estiver lucky), seguido por alguma combinação de gc_stale_time e gc_interval passando antes que ele seja realmente limpo (assim, no geral, algo entre 5-10 minutos passará).

Resumo: você pode tentar diminuir / proc / sys / net / ipv4 / route / gc_timeout para um valor menor, mas há muitas variáveis e é difícil controlá-las. Há um grande esforço para que as coisas funcionem bem, não removendo as entradas no cache muito cedo (mas apenas marcando-as como STALE ou até FAILED).

    
por 20.04.2016 / 20:51
0

O doc do Kernel.org indica que

route/max_size - INTEGER
    Maximum number of routes allowed in the kernel.  Increase
    this when using large numbers of interfaces and/or routes.
    From linux kernel 3.6 onwards, this is deprecated for ipv4
    as route cache is no longer used.

/proc/sys/net/ipv4/route/gc_timeout é bem diferente da tabela de referência em sua implicação e o caching de rota não é mais usado para ip4. Se você fizer um sysctl net.ipv4.route.gc_thresh , provavelmente verá que está definido como -1

    
por 14.06.2018 / 18:08
0

na função neigh_periodic_work , existe o código abaixo:

if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
        goto out;
out:
    /* Cycle through all hash buckets every BASE_REACHABLE_TIME/2 ticks.
     * ARP entry timeouts range from 1/2 BASE_REACHABLE_TIME to 3/2
     * BASE_REACHABLE_TIME.
     */
    schedule_delayed_work(&tbl->gc_work,
                  NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME) >> 1);
    write_unlock_bh(&tbl->lock);

se o número de vizinhos for menor que gc_thresh1, então goto out, a tarefa de gc é atrasada, então não é possível deletar as tabelas vizinhas STALE e FAILED, você pode modificar o valor de /proc/sys/net/ipv4/neigh/default/gc_thresh1 , padrão 128 para% do kernel3.10.0-327.36.3

    
por 17.07.2018 / 09:07

Tags