diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 21 |
1 files changed, 18 insertions, 3 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); |