Le mardi 21 février 2012 à 20:15 +0100, Eric Dumazet a écrit :
Le mardi 21 février 2012 à 14:07 -0500, David Miller a écrit :
quoted
From: Eric Dumazet <redacted>
Date: Tue, 21 Feb 2012 20:03:24 +0100
quoted
But I dont know enough this code to know if the following patch is the
way to fix this. (and __neigh_for_each_release() can also be deleted if
no users left in tree)
I think instead of removing the code, we need to have it iterate over
"arp_tbl" but only invoke the callback for devices which are of type
ATM.
That makes sense...
Or invoke callback for all entries, and filter in callback non ATM ones.
What about following patch ?
Meelis, can you test it please ?
[PATCH] atm: clip: remove clip_tbl
Commit 32092ecf0644 (atm: clip: Use device neigh support on top of
"arp_tbl".) introduced a bug since clip_tbl is zeroed : Crash occurs in
__neigh_for_each_release()
idle_timer_check() must use instead arp_tbl and neigh_check_cb() should
ignore non clip neighbours.
Idea from David Miller.
Reported-by: Meelis Roos <redacted>
Signed-off-by: Eric Dumazet <redacted>
---
net/atm/clip.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c258..127fe70 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -46,8 +46,8 @@
static struct net_device *clip_devs;
static struct atm_vcc *atmarpd;
-static struct neigh_table clip_tbl;
static struct timer_list idle_timer;
+static const struct neigh_ops clip_neigh_ops;
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
{@@ -123,6 +123,8 @@ static int neigh_check_cb(struct neighbour *n)
struct atmarp_entry *entry = neighbour_priv(n);
struct clip_vcc *cv;
+ if (n->ops != &clip_neigh_ops)
+ return 0;
for (cv = entry->vccs; cv; cv = cv->next) {
unsigned long exp = cv->last_use + cv->idle_timeout;
@@ -154,10 +156,10 @@ static int neigh_check_cb(struct neighbour *n)
static void idle_timer_check(unsigned long dummy)
{
- write_lock(&clip_tbl.lock);
- __neigh_for_each_release(&clip_tbl, neigh_check_cb);
+ write_lock(&arp_tbl.lock);
+ __neigh_for_each_release(&arp_tbl, neigh_check_cb);
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
- write_unlock(&clip_tbl.lock);
+ write_unlock(&arp_tbl.lock);
}
static int clip_arp_rcv(struct sk_buff *skb)