diff options
-rw-r--r-- | net/ipv4/ip_gre.c | 21 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 20 | ||||
-rw-r--r-- | net/ipv6/sit.c | 21 |
3 files changed, 55 insertions, 7 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 884835522224..f0d5740d7e22 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -290,7 +290,6 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
290 | 290 | ||
291 | dev_hold(dev); | 291 | dev_hold(dev); |
292 | ipgre_tunnel_link(nt); | 292 | ipgre_tunnel_link(nt); |
293 | /* Do not decrement MOD_USE_COUNT here. */ | ||
294 | return nt; | 293 | return nt; |
295 | 294 | ||
296 | failed: | 295 | failed: |
@@ -1277,12 +1276,28 @@ err1: | |||
1277 | goto out; | 1276 | goto out; |
1278 | } | 1277 | } |
1279 | 1278 | ||
1280 | static void ipgre_fini(void) | 1279 | static void __exit ipgre_destroy_tunnels(void) |
1280 | { | ||
1281 | int prio; | ||
1282 | |||
1283 | for (prio = 0; prio < 4; prio++) { | ||
1284 | int h; | ||
1285 | for (h = 0; h < HASH_SIZE; h++) { | ||
1286 | struct ip_tunnel *t; | ||
1287 | while ((t = tunnels[prio][h]) != NULL) | ||
1288 | unregister_netdevice(t->dev); | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | static void __exit ipgre_fini(void) | ||
1281 | { | 1294 | { |
1282 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) | 1295 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) |
1283 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); | 1296 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); |
1284 | 1297 | ||
1285 | unregister_netdev(ipgre_fb_tunnel_dev); | 1298 | rtnl_lock(); |
1299 | ipgre_destroy_tunnels(); | ||
1300 | rtnl_unlock(); | ||
1286 | } | 1301 | } |
1287 | 1302 | ||
1288 | module_init(ipgre_init); | 1303 | module_init(ipgre_init); |
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); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b788f55e139b..e553e5b80d6e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -195,7 +195,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
195 | dev_hold(dev); | 195 | dev_hold(dev); |
196 | 196 | ||
197 | ipip6_tunnel_link(nt); | 197 | ipip6_tunnel_link(nt); |
198 | /* Do not decrement MOD_USE_COUNT here. */ | ||
199 | return nt; | 198 | return nt; |
200 | 199 | ||
201 | failed: | 200 | failed: |
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol = { | |||
794 | .err_handler = ipip6_err, | 793 | .err_handler = ipip6_err, |
795 | }; | 794 | }; |
796 | 795 | ||
796 | static void __exit sit_destroy_tunnels(void) | ||
797 | { | ||
798 | int prio; | ||
799 | |||
800 | for (prio = 1; prio < 4; prio++) { | ||
801 | int h; | ||
802 | for (h = 0; h < HASH_SIZE; h++) { | ||
803 | struct ip_tunnel *t; | ||
804 | while ((t = tunnels[prio][h]) != NULL) | ||
805 | unregister_netdevice(t->dev); | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
797 | void __exit sit_cleanup(void) | 810 | void __exit sit_cleanup(void) |
798 | { | 811 | { |
799 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); | 812 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); |
800 | unregister_netdev(ipip6_fb_tunnel_dev); | 813 | |
814 | rtnl_lock(); | ||
815 | sit_destroy_tunnels(); | ||
816 | unregister_netdevice(ipip6_fb_tunnel_dev); | ||
817 | rtnl_unlock(); | ||
801 | } | 818 | } |
802 | 819 | ||
803 | int __init sit_init(void) | 820 | int __init sit_init(void) |