]> err.no Git - linux-2.6/blobdiff - drivers/net/tun.c
Merge branch 'for-2.6.25' of git://git.secretlab.ca/git/linux-2.6-mpc52xx into for...
[linux-2.6] / drivers / net / tun.c
index d279151f065d1a94183c819ee7146aec9fa9c586..038c1ef94d2e72e7332a4e28a86cbd82be14788a 100644 (file)
@@ -159,19 +159,30 @@ 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));
        }
 }
 
+#define MIN_MTU 68
+#define MAX_MTU 65535
+
+static int
+tun_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+       if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
+               return -EINVAL;
+       dev->mtu = new_mtu;
+       return 0;
+}
+
 /* Initialize net device. */
 static void tun_net_init(struct net_device *dev)
 {
@@ -183,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;
@@ -195,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)) );
@@ -279,17 +292,6 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
        return count;
 }
 
-static inline size_t iov_total(const struct iovec *iv, unsigned long count)
-{
-       unsigned long i;
-       size_t len;
-
-       for (i = 0, len = 0; i < count; i++)
-               len += iv[i].iov_len;
-
-       return len;
-}
-
 static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
                              unsigned long count, loff_t pos)
 {
@@ -300,7 +302,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 
        DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
 
-       return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
+       return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
 }
 
 /* Put packet to the user space buffer */
@@ -344,13 +346,14 @@ 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;
 
        DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
 
-       len = iov_total(iv, count);
+       len = iov_length(iv, count);
        if (len < 0)
                return -EINVAL;
 
@@ -398,16 +401,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;
                }
@@ -505,7 +506,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
                /* Be promiscuous by default to maintain previous behaviour. */
                tun->if_flags = IFF_PROMISC;
                /* Generate random Ethernet address. */
-               *(u16 *)tun->dev_addr = htons(0x00FF);
+               *(__be16 *)tun->dev_addr = htons(0x00FF);
                get_random_bytes(tun->dev_addr + sizeof(u16), 4);
                memset(tun->chr_filter, 0, sizeof tun->chr_filter);
 
@@ -528,9 +529,13 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
 
        if (ifr->ifr_flags & IFF_NO_PI)
                tun->flags |= TUN_NO_PI;
+       else
+               tun->flags &= ~TUN_NO_PI;
 
        if (ifr->ifr_flags & IFF_ONE_QUEUE)
                tun->flags |= TUN_ONE_QUEUE;
+       else
+               tun->flags &= ~TUN_ONE_QUEUE;
 
        file->private_data = tun;
        tun->attached = 1;
@@ -550,6 +555,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))
@@ -597,7 +603,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:
@@ -678,22 +684,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: