forked from Minki/linux
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
da6a8fa027
commit
32092ecf06
@ -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
|
||||
|
@ -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->tbl->family != AF_INET)
|
||||
return -EINVAL;
|
||||
|
||||
if (neigh->type != RTN_UNICAST)
|
||||
return -EINVAL;
|
||||
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get_rcu(dev);
|
||||
if (!in_dev) {
|
||||
rcu_read_unlock();
|
||||
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)
|
||||
|
@ -112,11 +112,6 @@
|
||||
#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>
|
||||
|
@ -108,7 +108,6 @@
|
||||
#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)
|
||||
|
Loading…
Reference in New Issue
Block a user