diff options
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r-- | net/ipv4/ipip.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index c3947cd566b7..c05c1df0bb04 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -255,7 +255,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c | |||
255 | 255 | ||
256 | dev_hold(dev); | 256 | dev_hold(dev); |
257 | ipip_tunnel_link(nt); | 257 | ipip_tunnel_link(nt); |
258 | /* Do not decrement MOD_USE_COUNT here. */ | ||
259 | return nt; | 258 | return nt; |
260 | 259 | ||
261 | failed: | 260 | failed: |
@@ -920,12 +919,29 @@ static int __init ipip_init(void) | |||
920 | goto out; | 919 | goto out; |
921 | } | 920 | } |
922 | 921 | ||
922 | static void __exit ipip_destroy_tunnels(void) | ||
923 | { | ||
924 | int prio; | ||
925 | |||
926 | for (prio = 1; prio < 4; prio++) { | ||
927 | int h; | ||
928 | for (h = 0; h < HASH_SIZE; h++) { | ||
929 | struct ip_tunnel *t; | ||
930 | while ((t = tunnels[prio][h]) != NULL) | ||
931 | unregister_netdevice(t->dev); | ||
932 | } | ||
933 | } | ||
934 | } | ||
935 | |||
923 | static void __exit ipip_fini(void) | 936 | static void __exit ipip_fini(void) |
924 | { | 937 | { |
925 | if (ipip_unregister() < 0) | 938 | if (ipip_unregister() < 0) |
926 | printk(KERN_INFO "ipip close: can't deregister tunnel\n"); | 939 | printk(KERN_INFO "ipip close: can't deregister tunnel\n"); |
927 | 940 | ||
928 | unregister_netdev(ipip_fb_tunnel_dev); | 941 | rtnl_lock(); |
942 | ipip_destroy_tunnels(); | ||
943 | unregister_netdevice(ipip_fb_tunnel_dev); | ||
944 | rtnl_unlock(); | ||
929 | } | 945 | } |
930 | 946 | ||
931 | module_init(ipip_init); | 947 | module_init(ipip_init); |