Re: PROBLEM: 2.4.37.9 destroying an Ethernet interface with permanent NUD leaves the kernels with undestroyable interfaces when ATM is compiled in

From: Sylvain Rochet
Date: Thu Apr 08 2010 - 09:47:19 EST


Hi,

On Wed, Apr 07, 2010 at 10:23:39PM +0200, Sylvain Rochet wrote:
> Hi,
>
> (...)
>
> I changed the family of the ATM table to AF_ATMPVC, of course it fixes
> the issue but I guess this is the wrong way to fix that.

Finally made a patch that follows what Linux 2.6 does, which consists of
having "netlink" and "no-netlink" tables.

Sylvain
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)

Attachment: signature.asc
Description: Digital signature