queue_work(ipoib_workqueue, &priv->restart_task);
 }
 
-static void ipoib_neigh_destructor(struct neighbour *n)
+static void ipoib_neigh_cleanup(struct neighbour *n)
 {
        struct ipoib_neigh *neigh;
        struct ipoib_dev_priv *priv = netdev_priv(n->dev);
        struct ipoib_ah *ah = NULL;
 
        ipoib_dbg(priv,
-                 "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
+                 "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
                  IPOIB_QPN(n->ha),
                  IPOIB_GID_RAW_ARG(n->ha + 4));
 
 
 static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
 {
-       parms->neigh_destructor = ipoib_neigh_destructor;
+       parms->neigh_cleanup = ipoib_neigh_cleanup;
 
        return 0;
 }
 
        struct net_device *dev;
        struct neigh_parms *next;
        int     (*neigh_setup)(struct neighbour *);
-       void    (*neigh_destructor)(struct neighbour *);
+       void    (*neigh_cleanup)(struct neighbour *);
        struct neigh_table *tbl;
 
        void    *sysctl_table;
 
        spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
 }
 
-static void clip_neigh_destroy(struct neighbour *neigh)
-{
-       DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh);
-       if (NEIGH2ENTRY(neigh)->vccs)
-               printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n");
-       NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD;
-}
-
 static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
 {
        DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
        /* parameters are copied from ARP ... */
        .parms = {
                .tbl                    = &clip_tbl,
-               .neigh_destructor       = clip_neigh_destroy,
                .base_reachable_time    = 30 * HZ,
                .retrans_time           = 1 * HZ,
                .gc_staletime           = 60 * HZ,
 
                                n->dead = 1;
                                shrunk  = 1;
                                write_unlock(&n->lock);
+                               if (n->parms->neigh_cleanup)
+                                       n->parms->neigh_cleanup(n);
                                neigh_release(n);
                                continue;
                        }
                                NEIGH_PRINTK2("neigh %p is stray.\n", n);
                        }
                        write_unlock(&n->lock);
+                       if (n->parms->neigh_cleanup)
+                               n->parms->neigh_cleanup(n);
                        neigh_release(n);
                }
        }
                        kfree(hh);
        }
 
-       if (neigh->parms->neigh_destructor)
-               (neigh->parms->neigh_destructor)(neigh);
-
        skb_queue_purge(&neigh->arp_queue);
 
        dev_put(neigh->dev);
                        *np = n->next;
                        n->dead = 1;
                        write_unlock(&n->lock);
+                       if (n->parms->neigh_cleanup)
+                               n->parms->neigh_cleanup(n);
                        neigh_release(n);
                        continue;
                }
                        } else
                                np = &n->next;
                        write_unlock(&n->lock);
-                       if (release)
+                       if (release) {
+                               if (n->parms->neigh_cleanup)
+                                       n->parms->neigh_cleanup(n);
                                neigh_release(n);
+                       }
                }
        }
 }