atm: clip: Use device neigh support on top of "arp_tbl".
[~shefty/rdma-dev.git] / net / atm / clip.c
index a9d3484..f3b3615 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <net/route.h> /* for struct rtable and routing */
 #include <net/icmp.h> /* icmp_send */
+#include <net/arp.h>
 #include <linux/param.h> /* for HZ */
 #include <linux/uaccess.h>
 #include <asm/byteorder.h> /* for htons etc. */
@@ -287,70 +288,23 @@ static const struct neigh_ops clip_neigh_ops = {
 static int clip_constructor(struct neighbour *neigh)
 {
        struct atmarp_entry *entry = neighbour_priv(neigh);
-       struct net_device *dev = neigh->dev;
-       struct in_device *in_dev;
-       struct neigh_parms *parms;
 
-       pr_debug("(neigh %p, entry %p)\n", neigh, entry);
-       neigh->type = inet_addr_type(&init_net, *((__be32 *) neigh->primary_key));
-       if (neigh->type != RTN_UNICAST)
+       if (neigh->tbl->family != AF_INET)
                return -EINVAL;
 
-       rcu_read_lock();
-       in_dev = __in_dev_get_rcu(dev);
-       if (!in_dev) {
-               rcu_read_unlock();
+       if (neigh->type != RTN_UNICAST)
                return -EINVAL;
-       }
-
-       parms = in_dev->arp_parms;
-       __neigh_parms_put(neigh->parms);
-       neigh->parms = neigh_parms_clone(parms);
-       rcu_read_unlock();
 
+       neigh->nud_state = NUD_NONE;
        neigh->ops = &clip_neigh_ops;
-       neigh->output = neigh->nud_state & NUD_VALID ?
-           neigh->ops->connected_output : neigh->ops->output;
+       neigh->output = neigh->ops->output;
        entry->neigh = neigh;
        entry->vccs = NULL;
        entry->expires = jiffies - 1;
+
        return 0;
 }
 
-static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd)
-{
-       return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd);
-}
-
-static struct neigh_table clip_tbl = {
-       .family         = AF_INET,
-       .key_len        = 4,
-       .hash           = clip_hash,
-       .constructor    = clip_constructor,
-       .id             = "clip_arp_cache",
-
-       /* parameters are copied from ARP ... */
-       .parms = {
-               .tbl                    = &clip_tbl,
-               .base_reachable_time    = 30 * HZ,
-               .retrans_time           = 1 * HZ,
-               .gc_staletime           = 60 * HZ,
-               .reachable_time         = 30 * HZ,
-               .delay_probe_time       = 5 * HZ,
-               .queue_len_bytes        = 64 * 1024,
-               .ucast_probes           = 3,
-               .mcast_probes           = 3,
-               .anycast_delay          = 1 * HZ,
-               .proxy_delay            = (8 * HZ) / 10,
-               .proxy_qlen             = 64,
-               .locktime               = 1 * HZ,
-       },
-       .gc_interval    = 30 * HZ,
-       .gc_thresh1     = 128,
-       .gc_thresh2     = 512,
-       .gc_thresh3     = 1024,
-};
-
 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
 
 /*
@@ -508,7 +462,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
        rt = ip_route_output(&init_net, ip, 0, 1, 0);
        if (IS_ERR(rt))
                return PTR_ERR(rt);
-       neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1);
+       neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1);
        ip_rt_put(rt);
        if (!neigh)
                return -ENOMEM;
@@ -529,7 +483,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
 }
 
 static const struct net_device_ops clip_netdev_ops = {
-       .ndo_start_xmit = clip_start_xmit,
+       .ndo_start_xmit         = clip_start_xmit,
+       .ndo_neigh_construct    = clip_constructor,
 };
 
 static void clip_setup(struct net_device *dev)
@@ -590,10 +545,8 @@ static int clip_device_event(struct notifier_block *this, unsigned long event,
        if (!net_eq(dev_net(dev), &init_net))
                return NOTIFY_DONE;
 
-       if (event == NETDEV_UNREGISTER) {
-               neigh_ifdown(&clip_tbl, dev);
+       if (event == NETDEV_UNREGISTER)
                return NOTIFY_DONE;
-       }
 
        /* ignore non-CLIP devices */
        if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops)
@@ -867,6 +820,9 @@ static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
 {
        struct clip_seq_state *state = (struct clip_seq_state *)_state;
 
+       if (n->dev->type != ARPHRD_ATM)
+               return NULL;
+
        return clip_seq_vcc_walk(state, neighbour_priv(n), pos);
 }
 
@@ -874,7 +830,7 @@ static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
 {
        struct clip_seq_state *state = seq->private;
        state->ns.neigh_sub_iter = clip_seq_sub_iter;
-       return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
+       return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_NEIGH_ONLY);
 }
 
 static int clip_seq_show(struct seq_file *seq, void *v)
@@ -920,9 +876,6 @@ static void atm_clip_exit_noproc(void);
 
 static int __init atm_clip_init(void)
 {
-       neigh_table_init_no_netlink(&clip_tbl);
-
-       clip_tbl_hook = &clip_tbl;
        register_atm_ioctl(&clip_ioctl_ops);
        register_netdevice_notifier(&clip_dev_notifier);
        register_inetaddr_notifier(&clip_inet_notifier);
@@ -959,12 +912,6 @@ static void atm_clip_exit_noproc(void)
         */
        del_timer_sync(&idle_timer);
 
-       /* Next, purge the table, so that the device
-        * unregister loop below does not hang due to
-        * device references remaining in the table.
-        */
-       neigh_ifdown(&clip_tbl, NULL);
-
        dev = clip_devs;
        while (dev) {
                next = PRIV(dev)->next;
@@ -972,11 +919,6 @@ static void atm_clip_exit_noproc(void)
                free_netdev(dev);
                dev = next;
        }
-
-       /* Now it is safe to fully shutdown whole table. */
-       neigh_table_clear(&clip_tbl);
-
-       clip_tbl_hook = NULL;
 }
 
 static void __exit atm_clip_exit(void)