diff options
author | David Miller <davem@davemloft.net> | 2011-07-24 20:01:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-30 18:51:03 -0500 |
commit | 32092ecf0644e91070f9eff4f6e1edda8f90aecc (patch) | |
tree | 3e2e2a111364f08653b79fd7404346e9f4b5ee84 /net/atm | |
parent | da6a8fa0275e2178c44a875374cae80d057538d1 (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.c | 86 |
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 = { | |||
287 | static int clip_constructor(struct neighbour *neigh) | 288 | static 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 | ||
320 | static 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 | |||
325 | static 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 | ||
531 | static const struct net_device_ops clip_netdev_ops = { | 485 | static 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 | ||
535 | static void clip_setup(struct net_device *dev) | 490 | 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 | 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 | ||
880 | static int clip_seq_show(struct seq_file *seq, void *v) | 836 | static int clip_seq_show(struct seq_file *seq, void *v) |
@@ -920,9 +876,6 @@ static void atm_clip_exit_noproc(void); | |||
920 | 876 | ||
921 | static int __init atm_clip_init(void) | 877 | static 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 | ||
982 | static void __exit atm_clip_exit(void) | 924 | static void __exit atm_clip_exit(void) |