diff -Nru linux-2.4.36.6.a/include/net/neighbour.h linux-2.4.36.6.b/include/net/neighbour.h --- linux-2.4.36.6.a/include/net/neighbour.h 2008-06-06 16:25:34.000000000 +0000 +++ linux-2.4.36.6.b/include/net/neighbour.h 2010-04-08 13:36:12.000000000 +0000 @@ -192,6 +192,7 @@ }; extern void neigh_table_init(struct neigh_table *tbl); +extern void neigh_table_init_no_netlink(struct neigh_table *tbl); extern int neigh_table_clear(struct neigh_table *tbl); extern struct neighbour * neigh_lookup(struct neigh_table *tbl, const void *pkey, diff -Nru linux-2.4.36.6.a/net/atm/clip.c linux-2.4.36.6.b/net/atm/clip.c --- linux-2.4.36.6.a/net/atm/clip.c 2008-06-06 16:25:34.000000000 +0000 +++ linux-2.4.36.6.b/net/atm/clip.c 2010-04-08 13:35:09.000000000 +0000 @@ -752,7 +752,7 @@ static int __init atm_clip_init(void) { - neigh_table_init(&clip_tbl); + neigh_table_init_no_netlink(&clip_tbl); clip_tbl_hook = &clip_tbl; atm_clip_ops_set(&__atm_clip_ops); diff -Nru linux-2.4.36.6.a/net/core/neighbour.c linux-2.4.36.6.b/net/core/neighbour.c --- linux-2.4.36.6.a/net/core/neighbour.c 2008-06-06 16:25:34.000000000 +0000 +++ linux-2.4.36.6.b/net/core/neighbour.c 2010-04-08 13:33:40.000000000 +0000 @@ -1248,7 +1248,7 @@ } -void neigh_table_init(struct neigh_table *tbl) +void neigh_table_init_no_netlink(struct neigh_table *tbl) { unsigned long now = jiffies; unsigned long phsize; @@ -1302,10 +1302,27 @@ tbl->last_flush = now; tbl->last_rand = now + tbl->parms.reachable_time*20; +} + +void neigh_table_init(struct neigh_table *tbl) +{ + struct neigh_table *tmp; + + neigh_table_init_no_netlink(tbl); write_lock(&neigh_tbl_lock); - tbl->next = neigh_tables; - neigh_tables = tbl; + for (tmp = neigh_tables; tmp; tmp = tmp->next) { + if (tmp->family == tbl->family) + break; + } + tbl->next = neigh_tables; + neigh_tables = tbl; write_unlock(&neigh_tbl_lock); + + if (unlikely(tmp)) { + printk(KERN_ERR "NEIGH: Registering multiple tables for " + "family %d\n", tbl->family); + dump_stack(); + } } int neigh_table_clear(struct neigh_table *tbl)