Subject: [PATCH] etun: Add a factory method. From: Eric W. Biederman Date: 1137565322 -0700 - Update the copyright information. - Add a factory method. --- drivers/net/etun.c | 54 +++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 43 insertions(+), 11 deletions(-) fc915e9e0aaa4d98cf75dff15c4f3d2ca84dc19c diff --git a/drivers/net/etun.c b/drivers/net/etun.c index e3062f5..d96ea4d 100644 --- a/drivers/net/etun.c +++ b/drivers/net/etun.c @@ -1,17 +1,19 @@ /* * ETUN - Universal ETUN device driver. - * Copyright (C) 2005 Eric Biederman + * Copyright (C) 2006 Linux Networx * */ #define DRV_NAME "etun" #define DRV_VERSION "1.0" -#define DRV_DESCRIPTION "Universal ETUN device driver" -#define DRV_COPYRIGHT "(C) 2005 Eric Biederman " +#define DRV_DESCRIPTION "Ethernet tunnel device driver" +#define DRV_COPYRIGHT "(C) 2006 Linux Networx" #include #include #include +#include +#include #include #include #include @@ -31,10 +33,12 @@ */ #define ETUN_MUST_CHECKSUM 1 -#define MAX_ETUN 2 -static struct net_device *etun[MAX_ETUN]; +static DEFINE_SPINLOCK(etun_lock); +static LIST_HEAD(etun_list); struct etun_info { + struct list_head list; + struct net_device *dev; struct net_device *rx_dev; struct net_device_stats stats; }; @@ -142,10 +146,18 @@ static int etun_ioctl(struct net_device static struct net_device *etun_alloc(void) { struct net_device *dev; + struct etun_info *info; int err; dev = alloc_netdev(sizeof(struct etun_info), "etun%d", ether_setup); if (!dev) return ERR_PTR(-ENOMEM); + info = netdev_priv(dev); + info->dev = dev; + + spin_lock(&etun_lock); + list_add(&info->list, &etun_list); + spin_unlock(&etun_lock); + random_ether_addr(dev->dev_addr); dev->tx_queue_len = 0; /* A queue is silly for a loopback device */ dev->hard_start_xmit = etun_xmit; @@ -162,10 +174,14 @@ static struct net_device *etun_alloc(voi | NETIF_F_LLTX; dev->flags = IFF_BROADCAST | IFF_MULTICAST |IFF_PROMISC; dev->ethtool_ops = &etun_ethtool_ops; - dev->priv = netdev_priv(dev); + dev->priv = info; dev->destructor = free_netdev; err = register_netdev(dev); if (err) { + spin_lock(&etun_lock); + list_del(&info->list); + spin_unlock(&etun_lock); + free_netdev(dev); dev = ERR_PTR(err); } @@ -198,24 +214,40 @@ static int etun_alloc_pair(struct net_de return 0; } +static int etun_new(const char *val, struct kernel_param *kp) +{ + struct net_device *pair[2]; + return etun_alloc_pair(pair); +} + +static int etun_new_get(char *buffer, struct kernel_param *kp) +{ + return 0; +} + static int __init etun_init(void) { + struct net_device *pair[2]; printk(KERN_INFO "etun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO "etun: %s\n", DRV_COPYRIGHT); - return etun_alloc_pair(etun); + return etun_alloc_pair(pair); } static void etun_cleanup(void) { - int i; - for(i = 0; i < MAX_ETUN; i++) { - unregister_netdev(etun[i]); + struct etun_info *info, *tmp; + spin_lock(&etun_lock); + list_for_each_entry_safe(info, tmp, &etun_list, list) { + list_del(&info->list); + unregister_netdev(info->dev); } + spin_unlock(&etun_lock); } +module_param_call(new, etun_new, etun_new_get, NULL, S_IWUSR); module_init(etun_init); module_exit(etun_cleanup); MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_AUTHOR(DRV_COPYRIGHT); +MODULE_AUTHOR("Eric Biederman "); MODULE_LICENSE("GPL"); -- 1.0.GIT