Commit 32092ecf authored by David Miller's avatar David Miller Committed by David S. Miller

atm: clip: Use device neigh support on top of "arp_tbl".

Instead of instantiating an entire new neigh_table instance
just for ATM handling, use the neigh device private facility.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent da6a8fa0
...@@ -41,17 +41,12 @@ struct atmarp_entry { ...@@ -41,17 +41,12 @@ struct atmarp_entry {
struct neighbour *neigh; /* neighbour back-pointer */ struct neighbour *neigh; /* neighbour back-pointer */
}; };
#define PRIV(dev) ((struct clip_priv *) netdev_priv(dev)) #define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
struct clip_priv { struct clip_priv {
int number; /* for convenience ... */ int number; /* for convenience ... */
spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */ spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */
struct net_device *next; /* next CLIP interface */ struct net_device *next; /* next CLIP interface */
}; };
extern struct neigh_table *clip_tbl_hook;
#endif #endif
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <net/route.h> /* for struct rtable and routing */ #include <net/route.h> /* for struct rtable and routing */
#include <net/icmp.h> /* icmp_send */ #include <net/icmp.h> /* icmp_send */
#include <net/arp.h>
#include <linux/param.h> /* for HZ */ #include <linux/param.h> /* for HZ */
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/byteorder.h> /* for htons etc. */ #include <asm/byteorder.h> /* for htons etc. */
...@@ -287,70 +288,23 @@ static const struct neigh_ops clip_neigh_ops = { ...@@ -287,70 +288,23 @@ static const struct neigh_ops clip_neigh_ops = {
static int clip_constructor(struct neighbour *neigh) static int clip_constructor(struct neighbour *neigh)
{ {
struct atmarp_entry *entry = neighbour_priv(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); if (neigh->tbl->family != AF_INET)
neigh->type = inet_addr_type(&init_net, *((__be32 *) neigh->primary_key));
if (neigh->type != RTN_UNICAST)
return -EINVAL; return -EINVAL;
rcu_read_lock(); if (neigh->type != RTN_UNICAST)
in_dev = __in_dev_get_rcu(dev);
if (!in_dev) {
rcu_read_unlock();
return -EINVAL; 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->ops = &clip_neigh_ops;
neigh->output = neigh->nud_state & NUD_VALID ? neigh->output = neigh->ops->output;
neigh->ops->connected_output : neigh->ops->output;
entry->neigh = neigh; entry->neigh = neigh;
entry->vccs = NULL; entry->vccs = NULL;
entry->expires = jiffies - 1; entry->expires = jiffies - 1;
return 0; 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 */ /* @@@ 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) ...@@ -508,7 +462,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
rt = ip_route_output(&init_net, ip, 0, 1, 0); rt = ip_route_output(&init_net, ip, 0, 1, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))
return PTR_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); ip_rt_put(rt);
if (!neigh) if (!neigh)
return -ENOMEM; return -ENOMEM;
...@@ -529,7 +483,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) ...@@ -529,7 +483,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
} }
static const struct net_device_ops clip_netdev_ops = { 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) static void clip_setup(struct net_device *dev)
...@@ -590,10 +545,8 @@ static int clip_device_event(struct notifier_block *this, unsigned long event, ...@@ -590,10 +545,8 @@ static int clip_device_event(struct notifier_block *this, unsigned long event,
if (!net_eq(dev_net(dev), &init_net)) if (!net_eq(dev_net(dev), &init_net))
return NOTIFY_DONE; return NOTIFY_DONE;
if (event == NETDEV_UNREGISTER) { if (event == NETDEV_UNREGISTER)
neigh_ifdown(&clip_tbl, dev);
return NOTIFY_DONE; return NOTIFY_DONE;
}
/* ignore non-CLIP devices */ /* ignore non-CLIP devices */
if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) 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, ...@@ -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; 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); 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) ...@@ -874,7 +830,7 @@ static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
{ {
struct clip_seq_state *state = seq->private; struct clip_seq_state *state = seq->private;
state->ns.neigh_sub_iter = clip_seq_sub_iter; 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) static int clip_seq_show(struct seq_file *seq, void *v)
...@@ -920,9 +876,6 @@ static void atm_clip_exit_noproc(void); ...@@ -920,9 +876,6 @@ static void atm_clip_exit_noproc(void);
static int __init atm_clip_init(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_atm_ioctl(&clip_ioctl_ops);
register_netdevice_notifier(&clip_dev_notifier); register_netdevice_notifier(&clip_dev_notifier);
register_inetaddr_notifier(&clip_inet_notifier); register_inetaddr_notifier(&clip_inet_notifier);
...@@ -959,12 +912,6 @@ static void atm_clip_exit_noproc(void) ...@@ -959,12 +912,6 @@ static void atm_clip_exit_noproc(void)
*/ */
del_timer_sync(&idle_timer); 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; dev = clip_devs;
while (dev) { while (dev) {
next = PRIV(dev)->next; next = PRIV(dev)->next;
...@@ -972,11 +919,6 @@ static void atm_clip_exit_noproc(void) ...@@ -972,11 +919,6 @@ static void atm_clip_exit_noproc(void)
free_netdev(dev); free_netdev(dev);
dev = next; 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) static void __exit atm_clip_exit(void)
......
...@@ -112,11 +112,6 @@ ...@@ -112,11 +112,6 @@
#include <net/arp.h> #include <net/arp.h>
#include <net/ax25.h> #include <net/ax25.h>
#include <net/netrom.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 <asm/system.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
......
...@@ -108,7 +108,6 @@ ...@@ -108,7 +108,6 @@
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
#include <linux/sysctl.h> #include <linux/sysctl.h>
#endif #endif
#include <net/atmclip.h>
#include <net/secure_seq.h> #include <net/secure_seq.h>
#define RT_FL_TOS(oldflp4) \ #define RT_FL_TOS(oldflp4) \
...@@ -1013,23 +1012,18 @@ static int slow_chain_length(const struct rtable *head) ...@@ -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) 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; static const __be32 inaddr_any = 0;
struct net_device *dev = dst->dev; struct net_device *dev = dst->dev;
const __be32 *pkey = daddr; const __be32 *pkey = daddr;
struct neighbour *n; 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)) if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
pkey = &inaddr_any; pkey = &inaddr_any;
n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey); n = __ipv4_neigh_lookup(&arp_tbl, dev, *(__force u32 *)pkey);
if (n) if (n)
return n; return n;
return neigh_create(tbl, pkey, dev); return neigh_create(&arp_tbl, pkey, dev);
} }
static int rt_bind_neighbour(struct rtable *rt) static int rt_bind_neighbour(struct rtable *rt)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment