diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 038c1ef94d2..5b5d87585d9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -67,10 +67,43 @@ #include <asm/system.h> #include <asm/uaccess.h> +/* Uncomment to enable debugging */ +/* #define TUN_DEBUG 1 */ + #ifdef TUN_DEBUG static int debug; + +#define DBG if(tun->debug)printk +#define DBG1 if(debug==2)printk +#else +#define DBG( a... ) +#define DBG1( a... ) #endif +struct tun_struct { + struct list_head list; + unsigned long flags; + int attached; + uid_t owner; + gid_t group; + + wait_queue_head_t read_wait; + struct sk_buff_head readq; + + struct net_device *dev; + + struct fasync_struct *fasync; + + unsigned long if_flags; + u8 dev_addr[ETH_ALEN]; + u32 chr_filter[2]; + u32 net_filter[2]; + +#ifdef TUN_DEBUG + int debug; +#endif +}; + /* Network device part of the driver */ static LIST_HEAD(tun_dev_list); @@ -253,8 +286,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, return -EFAULT; } - if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) + if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { align = NET_IP_ALIGN; + if (unlikely(len < ETH_HLEN)) + return -EINVAL; + } if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { tun->dev->stats.rx_dropped++; @@ -663,7 +699,11 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, case SIOCSIFHWADDR: { /* try to set the actual net device's hw address */ - int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + int ret; + + rtnl_lock(); + ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + rtnl_unlock(); if (ret == 0) { /** Set the character device's hardware address. This is used when |