aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2011-07-24 20:01:41 -0400
committerDavid S. Miller <davem@davemloft.net>2011-11-30 18:51:03 -0500
commit32092ecf0644e91070f9eff4f6e1edda8f90aecc (patch)
tree3e2e2a111364f08653b79fd7404346e9f4b5ee84 /net/atm
parentda6a8fa0275e2178c44a875374cae80d057538d1 (diff)
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>
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/clip.c86
1 files changed, 14 insertions, 72 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index a9d3484b1e71..f3b36154b0c5 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -33,6 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <net/route.h> /* for struct rtable and routing */ 34#include <net/route.h> /* for struct rtable and routing */
35#include <net/icmp.h> /* icmp_send */ 35#include <net/icmp.h> /* icmp_send */
36#include <net/arp.h>
36#include <linux/param.h> /* for HZ */ 37#include <linux/param.h> /* for HZ */
37#include <linux/uaccess.h> 38#include <linux/uaccess.h>
38#include <asm/byteorder.h> /* for htons etc. */ 39#include <asm/byteorder.h> /* for htons etc. */
@@ -287,70 +288,23 @@ static const struct neigh_ops clip_neigh_ops = {
287static int clip_constructor(struct neighbour *neigh) 288static int clip_constructor(struct neighbour *neigh)
288{ 289{
289 struct atmarp_entry *entry = neighbour_priv(neigh); 290 struct atmarp_entry *entry = neighbour_priv(neigh);
290 struct net_device *dev = neigh->dev;
291 struct in_device *in_dev;
292 struct neigh_parms *parms;
293 291
294 pr_debug("(neigh %p, entry %p)\n", neigh, entry); 292 if (neigh->tbl->family != AF_INET)
295 neigh->type = inet_addr_type(&init_net, *((__be32 *) neigh->primary_key));
296 if (neigh->type != RTN_UNICAST)
297 return -EINVAL; 293 return -EINVAL;
298 294
299 rcu_read_lock(); 295 if (neigh->type != RTN_UNICAST)
300 in_dev = __in_dev_get_rcu(dev);
301 if (!in_dev) {
302 rcu_read_unlock();
303 return -EINVAL; 296 return -EINVAL;
304 }
305
306 parms = in_dev->arp_parms;
307 __neigh_parms_put(neigh->parms);
308 neigh->parms = neigh_parms_clone(parms);
309 rcu_read_unlock();
310 297
298 neigh->nud_state = NUD_NONE;
311 neigh->ops = &clip_neigh_ops; 299 neigh->ops = &clip_neigh_ops;
312 neigh->output = neigh->nud_state & NUD_VALID ? 300 neigh->output = neigh->ops->output;
313 neigh->ops->connected_output : neigh->ops->output;
314 entry->neigh = neigh; 301 entry->neigh = neigh;
315 entry->vccs = NULL; 302 entry->vccs = NULL;
316 entry->expires = jiffies - 1; 303 entry->expires = jiffies - 1;
304
317 return 0; 305 return 0;
318} 306}
319 307
320static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd)
321{
322 return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd);
323}
324
325static struct neigh_table clip_tbl = {
326 .family = AF_INET,
327 .key_len = 4,
328 .hash = clip_hash,
329 .constructor = clip_constructor,
330 .id = "clip_arp_cache",
331
332 /* parameters are copied from ARP ... */
333 .parms = {
334 .tbl = &clip_tbl,
335 .base_reachable_time = 30 * HZ,
336 .retrans_time = 1 * HZ,
337 .gc_staletime = 60 * HZ,
338 .reachable_time = 30 * HZ,
339 .delay_probe_time = 5 * HZ,
340 .queue_len_bytes = 64 * 1024,
341 .ucast_probes = 3,
342 .mcast_probes = 3,
343 .anycast_delay = 1 * HZ,
344 .proxy_delay = (8 * HZ) / 10,
345 .proxy_qlen = 64,
346 .locktime = 1 * HZ,
347 },
348 .gc_interval = 30 * HZ,
349 .gc_thresh1 = 128,
350 .gc_thresh2 = 512,
351 .gc_thresh3 = 1024,
352};
353
354/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */ 308/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
355 309
356/* 310/*
@@ -508,7 +462,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
508 rt = ip_route_output(&init_net, ip, 0, 1, 0); 462 rt = ip_route_output(&init_net, ip, 0, 1, 0);
509 if (IS_ERR(rt)) 463 if (IS_ERR(rt))
510 return PTR_ERR(rt); 464 return PTR_ERR(rt);
511 neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1); 465 neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1);
512 ip_rt_put(rt); 466 ip_rt_put(rt);
513 if (!neigh) 467 if (!neigh)
514 return -ENOMEM; 468 return -ENOMEM;
@@ -529,7 +483,8 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
529} 483}
530 484
531static const struct net_device_ops clip_netdev_ops = { 485static const struct net_device_ops clip_netdev_ops = {
532 .ndo_start_xmit = clip_start_xmit, 486 .ndo_start_xmit = clip_start_xmit,
487 .ndo_neigh_construct = clip_constructor,
533}; 488};
534 489
535static void clip_setup(struct net_device *dev) 490static void clip_setup(struct net_device *dev)
@@ -590,10 +545,8 @@ static int clip_device_event(struct notifier_block *this, unsigned long event,
590 if (!net_eq(dev_net(dev), &init_net)) 545 if (!net_eq(dev_net(dev), &init_net))
591 return NOTIFY_DONE; 546 return NOTIFY_DONE;
592 547
593 if (event == NETDEV_UNREGISTER) { 548 if (event == NETDEV_UNREGISTER)
594 neigh_ifdown(&clip_tbl, dev);
595 return NOTIFY_DONE; 549 return NOTIFY_DONE;
596 }
597 550
598 /* ignore non-CLIP devices */ 551 /* ignore non-CLIP devices */
599 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) 552 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{ 820{
868 struct clip_seq_state *state = (struct clip_seq_state *)_state; 821 struct clip_seq_state *state = (struct clip_seq_state *)_state;
869 822
823 if (n->dev->type != ARPHRD_ATM)
824 return NULL;
825
870 return clip_seq_vcc_walk(state, neighbour_priv(n), pos); 826 return clip_seq_vcc_walk(state, neighbour_priv(n), pos);
871} 827}
872 828
@@ -874,7 +830,7 @@ static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
874{ 830{
875 struct clip_seq_state *state = seq->private; 831 struct clip_seq_state *state = seq->private;
876 state->ns.neigh_sub_iter = clip_seq_sub_iter; 832 state->ns.neigh_sub_iter = clip_seq_sub_iter;
877 return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY); 833 return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_NEIGH_ONLY);
878} 834}
879 835
880static int clip_seq_show(struct seq_file *seq, void *v) 836static int clip_seq_show(struct seq_file *seq, void *v)
@@ -920,9 +876,6 @@ static void atm_clip_exit_noproc(void);
920 876
921static int __init atm_clip_init(void) 877static int __init atm_clip_init(void)
922{ 878{
923 neigh_table_init_no_netlink(&clip_tbl);
924
925 clip_tbl_hook = &clip_tbl;
926 register_atm_ioctl(&clip_ioctl_ops); 879 register_atm_ioctl(&clip_ioctl_ops);
927 register_netdevice_notifier(&clip_dev_notifier); 880 register_netdevice_notifier(&clip_dev_notifier);
928 register_inetaddr_notifier(&clip_inet_notifier); 881 register_inetaddr_notifier(&clip_inet_notifier);
@@ -959,12 +912,6 @@ static void atm_clip_exit_noproc(void)
959 */ 912 */
960 del_timer_sync(&idle_timer); 913 del_timer_sync(&idle_timer);
961 914
962 /* Next, purge the table, so that the device
963 * unregister loop below does not hang due to
964 * device references remaining in the table.
965 */
966 neigh_ifdown(&clip_tbl, NULL);
967
968 dev = clip_devs; 915 dev = clip_devs;
969 while (dev) { 916 while (dev) {
970 next = PRIV(dev)->next; 917 next = PRIV(dev)->next;
@@ -972,11 +919,6 @@ static void atm_clip_exit_noproc(void)
972 free_netdev(dev); 919 free_netdev(dev);
973 dev = next; 920 dev = next;
974 } 921 }
975
976 /* Now it is safe to fully shutdown whole table. */
977 neigh_table_clear(&clip_tbl);
978
979 clip_tbl_hook = NULL;
980} 922}
981 923
982static void __exit atm_clip_exit(void) 924static void __exit atm_clip_exit(void)