diff options
| -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 |
