Commit c18e4c72 authored by David S. Miller's avatar David S. Miller

[IPV4]: Do proper netdev module refcounting in tunnel drivers.

parent dfb1d7a5
...@@ -262,13 +262,10 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -262,13 +262,10 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
if (!create) if (!create)
return NULL; return NULL;
if (!try_module_get(THIS_MODULE))
return NULL;
dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL)
module_put(THIS_MODULE);
return NULL; return NULL;
}
memset(dev, 0, sizeof(*dev) + sizeof(*t)); memset(dev, 0, sizeof(*dev) + sizeof(*t));
dev->priv = (void*)(dev+1); dev->priv = (void*)(dev+1);
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
...@@ -288,6 +285,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -288,6 +285,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
goto failed; goto failed;
memcpy(nt->parms.name, dev->name, IFNAMSIZ); memcpy(nt->parms.name, dev->name, IFNAMSIZ);
} }
SET_MODULE_OWNER(dev);
if (register_netdevice(dev) < 0) if (register_netdevice(dev) < 0)
goto failed; goto failed;
...@@ -298,16 +296,13 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -298,16 +296,13 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
failed: failed:
kfree(dev); kfree(dev);
module_put(THIS_MODULE);
return NULL; return NULL;
} }
static void ipgre_tunnel_destructor(struct net_device *dev) static void ipgre_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipgre_fb_tunnel_dev) { if (dev != &ipgre_fb_tunnel_dev)
kfree(dev); kfree(dev);
module_put(THIS_MODULE);
}
} }
static void ipgre_tunnel_uninit(struct net_device *dev) static void ipgre_tunnel_uninit(struct net_device *dev)
...@@ -921,9 +916,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -921,9 +916,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
struct ip_tunnel_parm p; struct ip_tunnel_parm p;
struct ip_tunnel *t; struct ip_tunnel *t;
if (!try_module_get(THIS_MODULE))
return -EBUSY;
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
t = NULL; t = NULL;
...@@ -1037,7 +1029,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1037,7 +1029,6 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
} }
done: done:
module_put(THIS_MODULE);
return err; return err;
} }
...@@ -1117,8 +1108,6 @@ static int ipgre_open(struct net_device *dev) ...@@ -1117,8 +1108,6 @@ static int ipgre_open(struct net_device *dev)
{ {
struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
if (!try_module_get(THIS_MODULE))
return -EBUSY;
if (MULTICAST(t->parms.iph.daddr)) { if (MULTICAST(t->parms.iph.daddr)) {
struct flowi fl = { .oif = t->parms.link, struct flowi fl = { .oif = t->parms.link,
.nl_u = { .ip4_u = .nl_u = { .ip4_u =
...@@ -1127,16 +1116,12 @@ static int ipgre_open(struct net_device *dev) ...@@ -1127,16 +1116,12 @@ static int ipgre_open(struct net_device *dev)
.tos = RT_TOS(t->parms.iph.tos) } }, .tos = RT_TOS(t->parms.iph.tos) } },
.proto = IPPROTO_GRE }; .proto = IPPROTO_GRE };
struct rtable *rt; struct rtable *rt;
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl))
module_put(THIS_MODULE);
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
}
dev = rt->u.dst.dev; dev = rt->u.dst.dev;
ip_rt_put(rt); ip_rt_put(rt);
if (__in_dev_get(dev) == NULL) { if (__in_dev_get(dev) == NULL)
module_put(THIS_MODULE);
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
}
t->mlink = dev->ifindex; t->mlink = dev->ifindex;
ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr); ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr);
} }
...@@ -1153,7 +1138,6 @@ static int ipgre_close(struct net_device *dev) ...@@ -1153,7 +1138,6 @@ static int ipgre_close(struct net_device *dev)
in_dev_put(in_dev); in_dev_put(in_dev);
} }
} }
module_put(THIS_MODULE);
return 0; return 0;
} }
...@@ -1247,31 +1231,12 @@ static int ipgre_tunnel_init(struct net_device *dev) ...@@ -1247,31 +1231,12 @@ static int ipgre_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
#ifdef MODULE
static int ipgre_fb_tunnel_open(struct net_device *dev)
{
if (!try_module_get(THIS_MODULE))
return -EBUSY;
return 0;
}
static int ipgre_fb_tunnel_close(struct net_device *dev)
{
module_put(THIS_MODULE);
return 0;
}
#endif
int __init ipgre_fb_tunnel_init(struct net_device *dev) int __init ipgre_fb_tunnel_init(struct net_device *dev)
{ {
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct iphdr *iph; struct iphdr *iph;
ipgre_tunnel_init_gen(dev); ipgre_tunnel_init_gen(dev);
#ifdef MODULE
dev->open = ipgre_fb_tunnel_open;
dev->stop = ipgre_fb_tunnel_close;
#endif
iph = &ipgre_fb_tunnel.parms.iph; iph = &ipgre_fb_tunnel.parms.iph;
iph->version = 4; iph->version = 4;
...@@ -1295,11 +1260,7 @@ static struct inet_protocol ipgre_protocol = { ...@@ -1295,11 +1260,7 @@ static struct inet_protocol ipgre_protocol = {
* And now the modules code and kernel interface. * And now the modules code and kernel interface.
*/ */
#ifdef MODULE
int init_module(void)
#else
int __init ipgre_init(void) int __init ipgre_init(void)
#endif
{ {
printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
...@@ -1309,13 +1270,12 @@ int __init ipgre_init(void) ...@@ -1309,13 +1270,12 @@ int __init ipgre_init(void)
} }
ipgre_fb_tunnel_dev.priv = (void*)&ipgre_fb_tunnel; ipgre_fb_tunnel_dev.priv = (void*)&ipgre_fb_tunnel;
SET_MODULE_OWNER(&ipgre_fb_tunnel_dev);
register_netdev(&ipgre_fb_tunnel_dev); register_netdev(&ipgre_fb_tunnel_dev);
return 0; return 0;
} }
#ifdef MODULE void ipgre_fini(void)
void cleanup_module(void)
{ {
if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n"); printk(KERN_INFO "ipgre close: can't remove protocol\n");
...@@ -1323,5 +1283,8 @@ void cleanup_module(void) ...@@ -1323,5 +1283,8 @@ void cleanup_module(void)
unregister_netdev(&ipgre_fb_tunnel_dev); unregister_netdev(&ipgre_fb_tunnel_dev);
} }
#ifdef MODULE
module_init(ipgre_init);
#endif #endif
module_exit(ipgre_fini);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -231,13 +231,10 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -231,13 +231,10 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
if (!create) if (!create)
return NULL; return NULL;
if (!try_module_get(THIS_MODULE))
return NULL;
dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL)
module_put(THIS_MODULE);
return NULL; return NULL;
}
memset(dev, 0, sizeof(*dev) + sizeof(*t)); memset(dev, 0, sizeof(*dev) + sizeof(*t));
dev->priv = (void*)(dev+1); dev->priv = (void*)(dev+1);
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
...@@ -257,6 +254,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -257,6 +254,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
goto failed; goto failed;
memcpy(nt->parms.name, dev->name, IFNAMSIZ); memcpy(nt->parms.name, dev->name, IFNAMSIZ);
} }
SET_MODULE_OWNER(dev);
if (register_netdevice(dev) < 0) if (register_netdevice(dev) < 0)
goto failed; goto failed;
...@@ -267,16 +265,13 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -267,16 +265,13 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
failed: failed:
kfree(dev); kfree(dev);
module_put(THIS_MODULE);
return NULL; return NULL;
} }
static void ipip_tunnel_destructor(struct net_device *dev) static void ipip_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipip_fb_tunnel_dev) { if (dev != &ipip_fb_tunnel_dev)
kfree(dev); kfree(dev);
module_put(THIS_MODULE);
}
} }
static void ipip_tunnel_uninit(struct net_device *dev) static void ipip_tunnel_uninit(struct net_device *dev)
...@@ -683,9 +678,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -683,9 +678,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
struct ip_tunnel_parm p; struct ip_tunnel_parm p;
struct ip_tunnel *t; struct ip_tunnel *t;
if (!try_module_get(THIS_MODULE))
return -EBUSY;
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
t = NULL; t = NULL;
...@@ -784,7 +776,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -784,7 +776,6 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
} }
done: done:
module_put(THIS_MODULE);
return err; return err;
} }
...@@ -860,30 +851,11 @@ static int ipip_tunnel_init(struct net_device *dev) ...@@ -860,30 +851,11 @@ static int ipip_tunnel_init(struct net_device *dev)
return 0; return 0;
} }
#ifdef MODULE
static int ipip_fb_tunnel_open(struct net_device *dev)
{
if (!try_module_get(THIS_MODULE))
return -EBUSY;
return 0;
}
static int ipip_fb_tunnel_close(struct net_device *dev)
{
module_put(THIS_MODULE);
return 0;
}
#endif
int __init ipip_fb_tunnel_init(struct net_device *dev) int __init ipip_fb_tunnel_init(struct net_device *dev)
{ {
struct iphdr *iph; struct iphdr *iph;
ipip_tunnel_init_gen(dev); ipip_tunnel_init_gen(dev);
#ifdef MODULE
dev->open = ipip_fb_tunnel_open;
dev->stop = ipip_fb_tunnel_close;
#endif
iph = &ipip_fb_tunnel.parms.iph; iph = &ipip_fb_tunnel.parms.iph;
iph->version = 4; iph->version = 4;
...@@ -913,6 +885,7 @@ int __init ipip_init(void) ...@@ -913,6 +885,7 @@ int __init ipip_init(void)
} }
ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel; ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel;
SET_MODULE_OWNER(&ipip_fb_tunnel_dev);
register_netdev(&ipip_fb_tunnel_dev); register_netdev(&ipip_fb_tunnel_dev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment