diff options
Diffstat (limited to 'net/atm/clip.c')
-rw-r--r-- | net/atm/clip.c | 42 |
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 | ||
615 | static int clip_device_event(struct notifier_block *this,unsigned long event, | 615 | static 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 = { | |||
686 | static void atmarpd_close(struct atm_vcc *vcc) | 693 | static 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 | ||
715 | static int atm_init_atmarp(struct atm_vcc *vcc) | 720 | static 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 |