summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--quicktun.c49
1 files changed, 13 insertions, 36 deletions
diff --git a/quicktun.c b/quicktun.c
index 1aa426b..f24e25d 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -3,8 +3,8 @@
#include <linux/if_arp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <linux/list.h>
#include <linux/netdevice.h>
-#include <linux/rculist.h>
#include <linux/udp.h>
#include <net/dst.h>
#include <net/genetlink.h>
@@ -28,6 +28,8 @@ static LIST_HEAD(quicktun_list);
struct quicktun_struct {
+ struct list_head list;
+
struct net_device *dev;
unsigned long flags;
@@ -38,13 +40,6 @@ struct quicktun_struct {
};
-struct quicktun_list_entry {
- struct list_head list;
- struct rcu_head rcu;
- struct quicktun_struct *quicktun;
-};
-
-
static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct quicktun_struct *tun = netdev_priv(dev);
@@ -276,7 +271,6 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
struct quicktun_struct *tun;
struct net *net = genl_info_net(info);
struct net_device *dev;
- struct quicktun_list_entry *entry;
char *name = "qt%d";
int err;
@@ -298,20 +292,16 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
if (info->attrs[QUICKTUN_A_IFNAME])
name = nla_data(info->attrs[QUICKTUN_A_IFNAME]);
- entry = kmalloc(sizeof(struct quicktun_struct), GFP_KERNEL);
dev = alloc_netdev(sizeof(struct quicktun_struct), name, quicktun_setup);
- if (!entry || !dev) {
- err = -ENOMEM;
- goto err_free;
- }
+ if (!dev)
+ return -ENOMEM;
dev_net_set(dev, net);
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
- entry->quicktun = tun;
quicktun_net_init(dev);
@@ -337,7 +327,7 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
err = quicktun_socket_init(dev);
if (err < 0)
- goto err_free;
+ goto err_free_dev;
rtnl_lock();
@@ -351,7 +341,7 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
if (err < 0)
goto err_free_sk;
- list_add_tail_rcu(&entry->list, &quicktun_list);
+ list_add_tail(&tun->list, &quicktun_list);
rtnl_unlock();
@@ -361,30 +351,17 @@ static int quicktun_cmd_create_device(struct sk_buff *skb, struct genl_info *inf
rtnl_unlock();
sock_release(tun->sock);
- err_free:
- if (dev) free_netdev(dev);
- if (entry) kfree(entry);
+ err_free_dev:
+ free_netdev(dev);
return err;
}
-static void quicktun_free_list_entry(struct rcu_head *rcu) {
- struct quicktun_list_entry *entry = container_of(rcu, struct quicktun_list_entry, rcu);
- kfree(entry);
-}
static void __quicktun_delete_device(struct net_device *dev) {
struct quicktun_struct *tun = netdev_priv(dev);
struct socket *sock = tun->sock;
- struct quicktun_list_entry *entry = NULL;
-
- list_for_each_entry(entry, &quicktun_list, list) {
- if (entry->quicktun->dev == dev) {
- break;
- }
- }
- list_del_rcu(&entry->list);
- call_rcu(&entry->rcu, quicktun_free_list_entry);
+ list_del(&tun->list);
unregister_netdevice(dev);
sock_release(sock);
@@ -424,7 +401,7 @@ static int quicktun_cmd_delete_device(struct sk_buff *skb, struct genl_info *inf
return 0;
-err_unlock:
+ err_unlock:
rtnl_unlock();
return err;
@@ -475,14 +452,14 @@ static int __init quicktun_init(void)
static void quicktun_exit(void)
{
- struct quicktun_list_entry *entry, *next;
+ struct quicktun_struct *entry, *next;
genl_unregister_family(&quicktun_nl_family);
rtnl_lock();
list_for_each_entry_safe(entry, next, &quicktun_list, list) {
- __quicktun_delete_device(entry->quicktun->dev);
+ __quicktun_delete_device(entry->dev);
}
rtnl_unlock();