aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/atm/clip.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 3ab4e7947bab..5841c30384a4 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -613,12 +613,19 @@ static int clip_create(int number)
613 613
614 614
615static int clip_device_event(struct notifier_block *this,unsigned long event, 615static int clip_device_event(struct notifier_block *this,unsigned long event,
616 void *dev) 616 void *arg)
617{ 617{
618 struct net_device *dev = arg;
619
620 if (event == NETDEV_UNREGISTER) {
621 neigh_ifdown(&clip_tbl, dev);
622 return NOTIFY_DONE;
623 }
624
618 /* ignore non-CLIP devices */ 625 /* ignore non-CLIP devices */
619 if (((struct net_device *) dev)->type != ARPHRD_ATM || 626 if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit)
620 ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
621 return NOTIFY_DONE; 627 return NOTIFY_DONE;
628
622 switch (event) { 629 switch (event) {
623 case NETDEV_UP: 630 case NETDEV_UP:
624 DPRINTK("clip_device_event NETDEV_UP\n"); 631 DPRINTK("clip_device_event NETDEV_UP\n");
@@ -686,14 +693,12 @@ static struct notifier_block clip_inet_notifier = {
686static void atmarpd_close(struct atm_vcc *vcc) 693static void atmarpd_close(struct atm_vcc *vcc)
687{ 694{
688 DPRINTK("atmarpd_close\n"); 695 DPRINTK("atmarpd_close\n");
689 atmarpd = NULL; /* assumed to be atomic */ 696
690 barrier(); 697 rtnl_lock();
691 unregister_inetaddr_notifier(&clip_inet_notifier); 698 atmarpd = NULL;
692 unregister_netdevice_notifier(&clip_dev_notifier);
693 if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
694 printk(KERN_ERR "atmarpd_close: closing with requests "
695 "pending\n");
696 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); 699 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
700 rtnl_unlock();
701
697 DPRINTK("(done)\n"); 702 DPRINTK("(done)\n");
698 module_put(THIS_MODULE); 703 module_put(THIS_MODULE);
699} 704}
@@ -714,7 +719,12 @@ static struct atm_dev atmarpd_dev = {
714 719
715static int atm_init_atmarp(struct atm_vcc *vcc) 720static int atm_init_atmarp(struct atm_vcc *vcc)
716{ 721{
717 if (atmarpd) return -EADDRINUSE; 722 rtnl_lock();
723 if (atmarpd) {
724 rtnl_unlock();
725 return -EADDRINUSE;
726 }
727
718 if (start_timer) { 728 if (start_timer) {
719 start_timer = 0; 729 start_timer = 0;
720 init_timer(&idle_timer); 730 init_timer(&idle_timer);
@@ -731,10 +741,7 @@ static int atm_init_atmarp(struct atm_vcc *vcc)
731 vcc->push = NULL; 741 vcc->push = NULL;
732 vcc->pop = NULL; /* crash */ 742 vcc->pop = NULL; /* crash */
733 vcc->push_oam = NULL; /* crash */ 743 vcc->push_oam = NULL; /* crash */
734 if (register_netdevice_notifier(&clip_dev_notifier)) 744 rtnl_unlock();
735 printk(KERN_ERR "register_netdevice_notifier failed\n");
736 if (register_inetaddr_notifier(&clip_inet_notifier))
737 printk(KERN_ERR "register_inetaddr_notifier failed\n");
738 return 0; 745 return 0;
739} 746}
740 747
@@ -992,6 +999,8 @@ static int __init atm_clip_init(void)
992 999
993 clip_tbl_hook = &clip_tbl; 1000 clip_tbl_hook = &clip_tbl;
994 register_atm_ioctl(&clip_ioctl_ops); 1001 register_atm_ioctl(&clip_ioctl_ops);
1002 register_netdevice_notifier(&clip_dev_notifier);
1003 register_inetaddr_notifier(&clip_inet_notifier);
995 1004
996#ifdef CONFIG_PROC_FS 1005#ifdef CONFIG_PROC_FS
997{ 1006{
@@ -1012,6 +1021,9 @@ static void __exit atm_clip_exit(void)
1012 1021
1013 remove_proc_entry("arp", atm_proc_root); 1022 remove_proc_entry("arp", atm_proc_root);
1014 1023
1024 unregister_inetaddr_notifier(&clip_inet_notifier);
1025 unregister_netdevice_notifier(&clip_dev_notifier);
1026
1015 deregister_atm_ioctl(&clip_ioctl_ops); 1027 deregister_atm_ioctl(&clip_ioctl_ops);
1016 1028
1017 /* First, stop the idle timer, so it stops banging 1029 /* First, stop the idle timer, so it stops banging