]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/tun.c
dl2k: BMCR_t fixes
[linux-2.6-omap-h63xx.git] / drivers / net / tun.c
index 62b2b3005019c90865ef0f019f16d8d2607089f0..f8b8c71187a076f426b40833f5631d9445c9fdf0 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
 #include <linux/crc32.h>
+#include <net/net_namespace.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -109,7 +110,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 
                        /* We won't see all dropped packets individually, so overrun
                         * error is more appropriate. */
-                       tun->stats.tx_fifo_errors++;
+                       dev->stats.tx_fifo_errors++;
                } else {
                        /* Single queue mode.
                         * Driver handles dropping of all packets itself. */
@@ -128,7 +129,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
        return 0;
 
 drop:
-       tun->stats.tx_dropped++;
+       dev->stats.tx_dropped++;
        kfree_skb(skb);
        return 0;
 }
@@ -158,23 +159,28 @@ tun_net_mclist(struct net_device *dev)
        struct tun_struct *tun = netdev_priv(dev);
        const struct dev_mc_list *mclist;
        int i;
+       DECLARE_MAC_BUF(mac);
        DBG(KERN_DEBUG "%s: tun_net_mclist: mc_count %d\n",
                        dev->name, dev->mc_count);
        memset(tun->chr_filter, 0, sizeof tun->chr_filter);
        for (i = 0, mclist = dev->mc_list; i < dev->mc_count && mclist != NULL;
                        i++, mclist = mclist->next) {
                add_multi(tun->net_filter, mclist->dmi_addr);
-               DBG(KERN_DEBUG "%s: tun_net_mclist: %x:%x:%x:%x:%x:%x\n",
-                               dev->name,
-                               mclist->dmi_addr[0], mclist->dmi_addr[1], mclist->dmi_addr[2],
-                               mclist->dmi_addr[3], mclist->dmi_addr[4], mclist->dmi_addr[5]);
+               DBG(KERN_DEBUG "%s: tun_net_mclist: %s\n",
+                   dev->name, print_mac(mac, mclist->dmi_addr));
        }
 }
 
-static struct net_device_stats *tun_net_stats(struct net_device *dev)
+#define MIN_MTU 68
+#define MAX_MTU 65535
+
+static int
+tun_net_change_mtu(struct net_device *dev, int new_mtu)
 {
-       struct tun_struct *tun = netdev_priv(dev);
-       return &tun->stats;
+       if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
+               return -EINVAL;
+       dev->mtu = new_mtu;
+       return 0;
 }
 
 /* Initialize net device. */
@@ -188,6 +194,7 @@ static void tun_net_init(struct net_device *dev)
                dev->hard_header_len = 0;
                dev->addr_len = 0;
                dev->mtu = 1500;
+               dev->change_mtu = tun_net_change_mtu;
 
                /* Zero header length */
                dev->type = ARPHRD_NONE;
@@ -200,6 +207,7 @@ static void tun_net_init(struct net_device *dev)
                dev->set_multicast_list = tun_net_mclist;
 
                ether_setup(dev);
+               dev->change_mtu = tun_net_change_mtu;
 
                /* random address already created for us by tun_set_iff, use it */
                memcpy(dev->dev_addr, tun->dev_addr, min(sizeof(tun->dev_addr), sizeof(dev->dev_addr)) );
@@ -249,14 +257,14 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
                align = NET_IP_ALIGN;
 
        if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
-               tun->stats.rx_dropped++;
+               tun->dev->stats.rx_dropped++;
                return -ENOMEM;
        }
 
        if (align)
                skb_reserve(skb, align);
        if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
-               tun->stats.rx_dropped++;
+               tun->dev->stats.rx_dropped++;
                kfree_skb(skb);
                return -EFAULT;
        }
@@ -278,8 +286,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
        netif_rx_ni(skb);
        tun->dev->last_rx = jiffies;
 
-       tun->stats.rx_packets++;
-       tun->stats.rx_bytes += len;
+       tun->dev->stats.rx_packets++;
+       tun->dev->stats.rx_bytes += len;
 
        return count;
 }
@@ -335,8 +343,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
        skb_copy_datagram_iovec(skb, 0, iv, len);
        total += len;
 
-       tun->stats.tx_packets++;
-       tun->stats.tx_bytes += len;
+       tun->dev->stats.tx_packets++;
+       tun->dev->stats.tx_bytes += len;
 
        return total;
 }
@@ -349,6 +357,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
        DECLARE_WAITQUEUE(wait, current);
        struct sk_buff *skb;
        ssize_t len, ret = 0;
+       DECLARE_MAC_BUF(mac);
 
        if (!tun)
                return -EBADFD;
@@ -403,16 +412,14 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
                                  (addr[0] == 0x33 && addr[1] == 0x33)) &&
                                 ((tun->if_flags & IFF_ALLMULTI) ||
                                  (tun->chr_filter[bit_nr >> 5] & (1 << (bit_nr & 31)))))) {
-                       DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %x:%x:%x:%x:%x:%x\n",
-                                       tun->dev->name, addr[0], addr[1], addr[2],
-                                       addr[3], addr[4], addr[5]);
+                       DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %s\n",
+                                       tun->dev->name, print_mac(mac, addr));
                        ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
                        kfree_skb(skb);
                        break;
                } else {
-                       DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %x:%x:%x:%x:%x:%x\n",
-                                       tun->dev->name, addr[0], addr[1], addr[2],
-                                       addr[3], addr[4], addr[5]);
+                       DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %s\n",
+                                       tun->dev->name, print_mac(mac, addr));
                        kfree_skb(skb);
                        continue;
                }
@@ -434,11 +441,9 @@ static void tun_setup(struct net_device *dev)
        tun->owner = -1;
        tun->group = -1;
 
-       SET_MODULE_OWNER(dev);
        dev->open = tun_net_open;
        dev->hard_start_xmit = tun_net_xmit;
        dev->stop = tun_net_close;
-       dev->get_stats = tun_net_stats;
        dev->ethtool_ops = &tun_ethtool_ops;
        dev->destructor = free_netdev;
 }
@@ -475,7 +480,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
                     !capable(CAP_NET_ADMIN))
                        return -EPERM;
        }
-       else if (__dev_get_by_name(ifr->ifr_name))
+       else if (__dev_get_by_name(&init_net, ifr->ifr_name))
                return -EINVAL;
        else {
                char *name;
@@ -557,6 +562,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
        struct tun_struct *tun = file->private_data;
        void __user* argp = (void __user*)arg;
        struct ifreq ifr;
+       DECLARE_MAC_BUF(mac);
 
        if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
                if (copy_from_user(&ifr, argp, sizeof ifr))
@@ -604,7 +610,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                        tun->flags &= ~TUN_PERSIST;
 
                DBG(KERN_INFO "%s: persist %s\n",
-                   tun->dev->name, arg ? "disabled" : "enabled");
+                   tun->dev->name, arg ? "enabled" : "disabled");
                break;
 
        case TUNSETOWNER:
@@ -685,22 +691,16 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                /** Add the specified group to the character device's multicast filter
                 * list. */
                add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
-               DBG(KERN_DEBUG "%s: add multi: %x:%x:%x:%x:%x:%x\n",
-                               tun->dev->name,
-                               (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
-                               (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
-                               (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
+               DBG(KERN_DEBUG "%s: add multi: %s\n",
+                   tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
                return 0;
 
        case SIOCDELMULTI:
                /** Remove the specified group from the character device's multicast
                 * filter list. */
                del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
-               DBG(KERN_DEBUG "%s: del multi: %x:%x:%x:%x:%x:%x\n",
-                               tun->dev->name,
-                               (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
-                               (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
-                               (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
+               DBG(KERN_DEBUG "%s: del multi: %s\n",
+                   tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
                return 0;
 
        default: