atm: clip: Use device neigh support on top of "arp_tbl".
authorDavid Miller <davem@davemloft.net>
Mon, 25 Jul 2011 00:01:41 +0000 (00:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Nov 2011 23:51:03 +0000 (18:51 -0500)
Instead of instantiating an entire new neigh_table instance
just for ATM handling, use the neigh device private facility.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/atmclip.h
net/atm/clip.c
net/ipv4/arp.c
net/ipv4/route.c

index 852a3b2890ecf118afd388e26a8c6ecd61084184..5865924d4aace7fd733e368021579099b4961982 100644 (file)
@@ -41,17 +41,12 @@ struct atmarp_entry {
        struct neighbour *neigh;        /* neighbour back-pointer */
 };
 
-
 #define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
 
-
 struct clip_priv {
        int number;                     /* for convenience ... */
        spinlock_t xoff_lock;           /* ensures that pop is atomic (SMP) */
        struct net_device *next;        /* next CLIP interface */
 };
 
-
-extern struct neigh_table *clip_tbl_hook;
-
 #endif
index a9d3484b1e71c61f96b598952a675c498787e0a6..f3b36154b0c5104b8228f5eb0bb99bde149b8d96 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)
index fd4b3e829a1855b565ea744fb5b76e13178cb70f..ff324ebc8893ae54772834bf2e424d01fafb0734 100644 (file)
 #include <net/arp.h>
 #include <net/ax25.h>
 #include <net/netrom.h>
-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
-#include <net/atmclip.h>
-struct neigh_table *clip_tbl_hook;
-EXPORT_SYMBOL(clip_tbl_hook);
-#endif
 
 #include <asm/system.h>
 #include <linux/uaccess.h>
index fb47c8f0cd86f689e087bea4dfea8f0c87f3e0a9..9a20663d5969cc390aaa37f95180a6b61917abca 100644 (file)
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
-#include <net/atmclip.h>
 #include <net/secure_seq.h>
 
 #define RT_FL_TOS(oldflp4) \
@@ -1013,23 +1012,18 @@ static int slow_chain_length(const struct rtable *head)
 
 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 {
-       struct neigh_table *tbl = &arp_tbl;
        static const __be32 inaddr_any = 0;
        struct net_device *dev = dst->dev;
        const __be32 *pkey = daddr;
        struct neighbour *n;
 
-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
-       if (dev->type == ARPHRD_ATM)
-               tbl = clip_tbl_hook;
-#endif
        if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
                pkey = &inaddr_any;
 
-       n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey);
+       n = __ipv4_neigh_lookup(&arp_tbl, dev, *(__force u32 *)pkey);
        if (n)
                return n;
-       return neigh_create(tbl, pkey, dev);
+       return neigh_create(&arp_tbl, pkey, dev);
 }
 
 static int rt_bind_neighbour(struct rtable *rt)