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 */
|
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 @@
|
||||||
#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 = {
|
||||||
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));
|
return -EINVAL;
|
||||||
|
|
||||||
if (neigh->type != RTN_UNICAST)
|
if (neigh->type != RTN_UNICAST)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rcu_read_lock();
|
neigh->nud_state = NUD_NONE;
|
||||||
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->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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue