Auf gute Nachbarschaft

Ein Server meldet regelmäßig "kernel: IPv4: Neighbour table overflow". Das tritt vor allem nachts auf, wenn nach der "Zwangstrennung" im DHCP neue IPs an die Broadbandkunden ausgeliefert wird. Offenbar ist die ARP-Tabelle übergelaufen.

Aber wie vergrößert man eine ARP Tabelle? Die Kerneldokumentation schweigt sich aus, die Hinweise in den Foren verschiedener Massenhoster verweisen auf gc_thresh1, gc_thresh2 und gc_thresh3. Alle drei Werte werden pauschal verdoppelt oder vervierfacht.

gc_thresh? Natürlich! Die ARP Tabelle ist nichts weiter als ein Cache, eine Ansammlung von Müll, der kontrolliert weggeworfen werden muß. Deswegen heißen die Kontrollparameter "Garbage Collection Threshold".

Der obligatorische Blick in die Quellen verwundert dann schon:

  • gc_thresh1 wird gar nicht benutzt
  • gc_thresh2 und gc_thresh3 tauchen nur an einer Stelle auf, in linux/net/core/neighbour.c
static struct neighbour *neigh_alloc(struct neigh_table *tbl)
{
        struct neighbour *n = NULL;
        unsigned long now = jiffies;
        int entries;

        entries = atomic_inc_return(&tbl->entries) - 1;
        if (entries >= tbl->gc_thresh3 ||
            (entries >= tbl->gc_thresh2 &&
             time_after(now, tbl->last_flush + 5 * HZ))) {
                if (!neigh_forced_gc(tbl) &&
                    entries >= tbl->gc_thresh3)
                        goto out_entries;
        }

        n = kmem_cache_zalloc(tbl->kmem_cachep, GFP_ATOMIC);
        if (!n)
                goto out_entries;

        ...
out:
        return n;

out_entries:
        atomic_dec(&tbl->entries);
        goto out;
}

Was mag der Code bedeuten? Die Originalquelle erklärt es sehr schön:

  • Die ARP-Tabelle bereinigt sich selbst, wenn ein Eintrag veraltet.
  • gc_thresh3 ist die Größe der ARP-Tabelle.
  • gc_thresh2 ist der Wert, ab dem die ARP-Tabelle alle fünf Sekunden um akut unbenutzte Einträge bereinigt wird.

Somit ist nun klar, welche Werte ich hier brauche. Für 15000 Kunden mit DHCP und DHCPv6 müssen entsprechend viele Plätze frein bleiben. Bei IPv6 etwas mehr, weil dort ja Privacy Extensions eine Vervielfachung der sichtbaren "Geräte" bedeutet.

echo  2000 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
echo 16000 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
echo  4000 > /proc/sys/net/ipv6/neigh/default/gc_thresh2
echo 25000 > /proc/sys/net/ipv6/neigh/default/gc_thresh3

Und tut.

Post a comment

Related content