Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

+17 -91
-5
include/net/atmclip.h
··· 41 41 struct neighbour *neigh; /* neighbour back-pointer */ 42 42 }; 43 43 44 - 45 44 #define PRIV(dev) ((struct clip_priv *) netdev_priv(dev)) 46 - 47 45 48 46 struct clip_priv { 49 47 int number; /* for convenience ... */ 50 48 spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */ 51 49 struct net_device *next; /* next CLIP interface */ 52 50 }; 53 - 54 - 55 - extern struct neigh_table *clip_tbl_hook; 56 51 57 52 #endif
+15 -73
net/atm/clip.c
··· 33 33 #include <linux/slab.h> 34 34 #include <net/route.h> /* for struct rtable and routing */ 35 35 #include <net/icmp.h> /* icmp_send */ 36 + #include <net/arp.h> 36 37 #include <linux/param.h> /* for HZ */ 37 38 #include <linux/uaccess.h> 38 39 #include <asm/byteorder.h> /* for htons etc. */ ··· 288 287 static int clip_constructor(struct neighbour *neigh) 289 288 { 290 289 struct atmarp_entry *entry = neighbour_priv(neigh); 291 - struct net_device *dev = neigh->dev; 292 - struct in_device *in_dev; 293 - struct neigh_parms *parms; 294 290 295 - pr_debug("(neigh %p, entry %p)\n", neigh, entry); 296 - neigh->type = inet_addr_type(&init_net, *((__be32 *) neigh->primary_key)); 291 + if (neigh->tbl->family != AF_INET) 292 + return -EINVAL; 293 + 297 294 if (neigh->type != RTN_UNICAST) 298 295 return -EINVAL; 299 296 300 - rcu_read_lock(); 301 - in_dev = __in_dev_get_rcu(dev); 302 - if (!in_dev) { 303 - rcu_read_unlock(); 304 - return -EINVAL; 305 - } 306 - 307 - parms = in_dev->arp_parms; 308 - __neigh_parms_put(neigh->parms); 309 - neigh->parms = neigh_parms_clone(parms); 310 - rcu_read_unlock(); 311 - 297 + neigh->nud_state = NUD_NONE; 312 298 neigh->ops = &clip_neigh_ops; 313 - neigh->output = neigh->nud_state & NUD_VALID ? 314 - neigh->ops->connected_output : neigh->ops->output; 299 + neigh->output = neigh->ops->output; 315 300 entry->neigh = neigh; 316 301 entry->vccs = NULL; 317 302 entry->expires = jiffies - 1; 303 + 318 304 return 0; 319 305 } 320 - 321 - static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd) 322 - { 323 - return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd); 324 - } 325 - 326 - static struct neigh_table clip_tbl = { 327 - .family = AF_INET, 328 - .key_len = 4, 329 - .hash = clip_hash, 330 - .constructor = clip_constructor, 331 - .id = "clip_arp_cache", 332 - 333 - /* parameters are copied from ARP ... */ 334 - .parms = { 335 - .tbl = &clip_tbl, 336 - .base_reachable_time = 30 * HZ, 337 - .retrans_time = 1 * HZ, 338 - .gc_staletime = 60 * HZ, 339 - .reachable_time = 30 * HZ, 340 - .delay_probe_time = 5 * HZ, 341 - .queue_len_bytes = 64 * 1024, 342 - .ucast_probes = 3, 343 - .mcast_probes = 3, 344 - .anycast_delay = 1 * HZ, 345 - .proxy_delay = (8 * HZ) / 10, 346 - .proxy_qlen = 64, 347 - .locktime = 1 * HZ, 348 - }, 349 - .gc_interval = 30 * HZ, 350 - .gc_thresh1 = 128, 351 - .gc_thresh2 = 512, 352 - .gc_thresh3 = 1024, 353 - }; 354 306 355 307 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */ 356 308 ··· 462 508 rt = ip_route_output(&init_net, ip, 0, 1, 0); 463 509 if (IS_ERR(rt)) 464 510 return PTR_ERR(rt); 465 - neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1); 511 + neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1); 466 512 ip_rt_put(rt); 467 513 if (!neigh) 468 514 return -ENOMEM; ··· 483 529 } 484 530 485 531 static const struct net_device_ops clip_netdev_ops = { 486 - .ndo_start_xmit = clip_start_xmit, 532 + .ndo_start_xmit = clip_start_xmit, 533 + .ndo_neigh_construct = clip_constructor, 487 534 }; 488 535 489 536 static void clip_setup(struct net_device *dev) ··· 545 590 if (!net_eq(dev_net(dev), &init_net)) 546 591 return NOTIFY_DONE; 547 592 548 - if (event == NETDEV_UNREGISTER) { 549 - neigh_ifdown(&clip_tbl, dev); 593 + if (event == NETDEV_UNREGISTER) 550 594 return NOTIFY_DONE; 551 - } 552 595 553 596 /* ignore non-CLIP devices */ 554 597 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) ··· 820 867 { 821 868 struct clip_seq_state *state = (struct clip_seq_state *)_state; 822 869 870 + if (n->dev->type != ARPHRD_ATM) 871 + return NULL; 872 + 823 873 return clip_seq_vcc_walk(state, neighbour_priv(n), pos); 824 874 } 825 875 ··· 830 874 { 831 875 struct clip_seq_state *state = seq->private; 832 876 state->ns.neigh_sub_iter = clip_seq_sub_iter; 833 - return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY); 877 + return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_NEIGH_ONLY); 834 878 } 835 879 836 880 static int clip_seq_show(struct seq_file *seq, void *v) ··· 876 920 877 921 static int __init atm_clip_init(void) 878 922 { 879 - neigh_table_init_no_netlink(&clip_tbl); 880 - 881 - clip_tbl_hook = &clip_tbl; 882 923 register_atm_ioctl(&clip_ioctl_ops); 883 924 register_netdevice_notifier(&clip_dev_notifier); 884 925 register_inetaddr_notifier(&clip_inet_notifier); ··· 912 959 */ 913 960 del_timer_sync(&idle_timer); 914 961 915 - /* Next, purge the table, so that the device 916 - * unregister loop below does not hang due to 917 - * device references remaining in the table. 918 - */ 919 - neigh_ifdown(&clip_tbl, NULL); 920 - 921 962 dev = clip_devs; 922 963 while (dev) { 923 964 next = PRIV(dev)->next; ··· 919 972 free_netdev(dev); 920 973 dev = next; 921 974 } 922 - 923 - /* Now it is safe to fully shutdown whole table. */ 924 - neigh_table_clear(&clip_tbl); 925 - 926 - clip_tbl_hook = NULL; 927 975 } 928 976 929 977 static void __exit atm_clip_exit(void)
-5
net/ipv4/arp.c
··· 112 112 #include <net/arp.h> 113 113 #include <net/ax25.h> 114 114 #include <net/netrom.h> 115 - #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 116 - #include <net/atmclip.h> 117 - struct neigh_table *clip_tbl_hook; 118 - EXPORT_SYMBOL(clip_tbl_hook); 119 - #endif 120 115 121 116 #include <asm/system.h> 122 117 #include <linux/uaccess.h>
+2 -8
net/ipv4/route.c
··· 108 108 #ifdef CONFIG_SYSCTL 109 109 #include <linux/sysctl.h> 110 110 #endif 111 - #include <net/atmclip.h> 112 111 #include <net/secure_seq.h> 113 112 114 113 #define RT_FL_TOS(oldflp4) \ ··· 1012 1013 1013 1014 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr) 1014 1015 { 1015 - struct neigh_table *tbl = &arp_tbl; 1016 1016 static const __be32 inaddr_any = 0; 1017 1017 struct net_device *dev = dst->dev; 1018 1018 const __be32 *pkey = daddr; 1019 1019 struct neighbour *n; 1020 1020 1021 - #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 1022 - if (dev->type == ARPHRD_ATM) 1023 - tbl = clip_tbl_hook; 1024 - #endif 1025 1021 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) 1026 1022 pkey = &inaddr_any; 1027 1023 1028 - n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey); 1024 + n = __ipv4_neigh_lookup(&arp_tbl, dev, *(__force u32 *)pkey); 1029 1025 if (n) 1030 1026 return n; 1031 - return neigh_create(tbl, pkey, dev); 1027 + return neigh_create(&arp_tbl, pkey, dev); 1032 1028 } 1033 1029 1034 1030 static int rt_bind_neighbour(struct rtable *rt)