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
					
				
			
		
					 4 changed files with 17 additions and 91 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			@ -530,6 +484,7 @@ 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_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…
	
	Add table
		Add a link
		
	
		Reference in a new issue