ia64/linux-2.6.18-xen.hg

view drivers/net/tun.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * TUN - Universal TUN/TAP device driver.
3 * Copyright (C) 1999-2002 Maxim Krasnyansky <maxk@qualcomm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $
16 */
18 /*
19 * Changes:
20 *
21 * Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14
22 * Add TUNSETLINK ioctl to set the link encapsulation
23 *
24 * Mark Smith <markzzzsmith@yahoo.com.au>
25 * Use random_ether_addr() for tap MAC address.
26 *
27 * Harald Roelle <harald.roelle@ifi.lmu.de> 2004/04/20
28 * Fixes in packet dropping, queue length setting and queue wakeup.
29 * Increased default tx queue length.
30 * Added ethtool API.
31 * Minor cleanups
32 *
33 * Daniel Podlejski <underley@underley.eu.org>
34 * Modifications for 2.3.99-pre5 kernel.
35 */
37 #define DRV_NAME "tun"
38 #define DRV_VERSION "1.6"
39 #define DRV_DESCRIPTION "Universal TUN/TAP device driver"
40 #define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>"
42 #include <linux/module.h>
43 #include <linux/errno.h>
44 #include <linux/kernel.h>
45 #include <linux/major.h>
46 #include <linux/slab.h>
47 #include <linux/poll.h>
48 #include <linux/fcntl.h>
49 #include <linux/init.h>
50 #include <linux/skbuff.h>
51 #include <linux/netdevice.h>
52 #include <linux/etherdevice.h>
53 #include <linux/miscdevice.h>
54 #include <linux/ethtool.h>
55 #include <linux/rtnetlink.h>
56 #include <linux/if.h>
57 #include <linux/if_arp.h>
58 #include <linux/if_ether.h>
59 #include <linux/if_tun.h>
60 #include <linux/crc32.h>
62 #include <asm/system.h>
63 #include <asm/uaccess.h>
65 #ifdef TUN_DEBUG
66 static int debug;
67 #endif
69 /* Network device part of the driver */
71 static LIST_HEAD(tun_dev_list);
72 static struct ethtool_ops tun_ethtool_ops;
74 /* Net device open. */
75 static int tun_net_open(struct net_device *dev)
76 {
77 netif_start_queue(dev);
78 return 0;
79 }
81 /* Net device close. */
82 static int tun_net_close(struct net_device *dev)
83 {
84 netif_stop_queue(dev);
85 return 0;
86 }
88 /* Net device start xmit */
89 static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
90 {
91 struct tun_struct *tun = netdev_priv(dev);
93 DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
95 /* Drop packet if interface is not attached */
96 if (!tun->attached)
97 goto drop;
99 /* Packet dropping */
100 if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
101 if (!(tun->flags & TUN_ONE_QUEUE)) {
102 /* Normal queueing mode. */
103 /* Packet scheduler handles dropping of further packets. */
104 netif_stop_queue(dev);
106 /* We won't see all dropped packets individually, so overrun
107 * error is more appropriate. */
108 tun->stats.tx_fifo_errors++;
109 } else {
110 /* Single queue mode.
111 * Driver handles dropping of all packets itself. */
112 goto drop;
113 }
114 }
116 /* Queue packet */
117 skb_queue_tail(&tun->readq, skb);
118 dev->trans_start = jiffies;
120 /* Notify and wake up reader process */
121 if (tun->flags & TUN_FASYNC)
122 kill_fasync(&tun->fasync, SIGIO, POLL_IN);
123 wake_up_interruptible(&tun->read_wait);
124 return 0;
126 drop:
127 tun->stats.tx_dropped++;
128 kfree_skb(skb);
129 return 0;
130 }
132 /** Add the specified Ethernet address to this multicast filter. */
133 static void
134 add_multi(u32* filter, const u8* addr)
135 {
136 int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
137 filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
138 }
140 /** Remove the specified Ethernet addres from this multicast filter. */
141 static void
142 del_multi(u32* filter, const u8* addr)
143 {
144 int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
145 filter[bit_nr >> 5] &= ~(1 << (bit_nr & 31));
146 }
148 /** Update the list of multicast groups to which the network device belongs.
149 * This list is used to filter packets being sent from the character device to
150 * the network device. */
151 static void
152 tun_net_mclist(struct net_device *dev)
153 {
154 struct tun_struct *tun = netdev_priv(dev);
155 const struct dev_mc_list *mclist;
156 int i;
157 DBG(KERN_DEBUG "%s: tun_net_mclist: mc_count %d\n",
158 dev->name, dev->mc_count);
159 memset(tun->chr_filter, 0, sizeof tun->chr_filter);
160 for (i = 0, mclist = dev->mc_list; i < dev->mc_count && mclist != NULL;
161 i++, mclist = mclist->next) {
162 add_multi(tun->net_filter, mclist->dmi_addr);
163 DBG(KERN_DEBUG "%s: tun_net_mclist: %x:%x:%x:%x:%x:%x\n",
164 dev->name,
165 mclist->dmi_addr[0], mclist->dmi_addr[1], mclist->dmi_addr[2],
166 mclist->dmi_addr[3], mclist->dmi_addr[4], mclist->dmi_addr[5]);
167 }
168 }
170 static struct net_device_stats *tun_net_stats(struct net_device *dev)
171 {
172 struct tun_struct *tun = netdev_priv(dev);
173 return &tun->stats;
174 }
176 /* Initialize net device. */
177 static void tun_net_init(struct net_device *dev)
178 {
179 struct tun_struct *tun = netdev_priv(dev);
181 switch (tun->flags & TUN_TYPE_MASK) {
182 case TUN_TUN_DEV:
183 /* Point-to-Point TUN Device */
184 dev->hard_header_len = 0;
185 dev->addr_len = 0;
186 dev->mtu = 1500;
188 /* Zero header length */
189 dev->type = ARPHRD_NONE;
190 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
191 dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
192 break;
194 case TUN_TAP_DEV:
195 /* Ethernet TAP Device */
196 dev->set_multicast_list = tun_net_mclist;
198 ether_setup(dev);
199 random_ether_addr(dev->dev_addr);
200 dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
201 break;
202 }
203 }
205 /* Character device part */
207 /* Poll */
208 static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
209 {
210 struct tun_struct *tun = file->private_data;
211 unsigned int mask = POLLOUT | POLLWRNORM;
213 if (!tun)
214 return -EBADFD;
216 DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
218 poll_wait(file, &tun->read_wait, wait);
220 if (!skb_queue_empty(&tun->readq))
221 mask |= POLLIN | POLLRDNORM;
223 return mask;
224 }
226 /* Get packet from user space buffer */
227 static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
228 {
229 struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
230 struct sk_buff *skb;
231 size_t len = count, align = 0;
233 if (!(tun->flags & TUN_NO_PI)) {
234 if ((len -= sizeof(pi)) > count)
235 return -EINVAL;
237 if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
238 return -EFAULT;
239 }
241 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV)
242 align = NET_IP_ALIGN;
244 if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
245 tun->stats.rx_dropped++;
246 return -ENOMEM;
247 }
249 if (align)
250 skb_reserve(skb, align);
251 if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
252 tun->stats.rx_dropped++;
253 kfree_skb(skb);
254 return -EFAULT;
255 }
257 skb->dev = tun->dev;
258 switch (tun->flags & TUN_TYPE_MASK) {
259 case TUN_TUN_DEV:
260 skb->mac.raw = skb->data;
261 skb->protocol = pi.proto;
262 break;
263 case TUN_TAP_DEV:
264 skb->protocol = eth_type_trans(skb, tun->dev);
265 break;
266 };
268 if (tun->flags & TUN_NOCHECKSUM)
269 skb->ip_summed = CHECKSUM_UNNECESSARY;
271 netif_rx_ni(skb);
272 tun->dev->last_rx = jiffies;
274 tun->stats.rx_packets++;
275 tun->stats.rx_bytes += len;
277 return count;
278 }
280 static inline size_t iov_total(const struct iovec *iv, unsigned long count)
281 {
282 unsigned long i;
283 size_t len;
285 for (i = 0, len = 0; i < count; i++)
286 len += iv[i].iov_len;
288 return len;
289 }
291 /* Writev */
292 static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
293 unsigned long count, loff_t *pos)
294 {
295 struct tun_struct *tun = file->private_data;
297 if (!tun)
298 return -EBADFD;
300 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
302 return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
303 }
305 /* Write */
306 static ssize_t tun_chr_write(struct file * file, const char __user * buf,
307 size_t count, loff_t *pos)
308 {
309 struct iovec iv = { (void __user *) buf, count };
310 return tun_chr_writev(file, &iv, 1, pos);
311 }
313 /* Put packet to the user space buffer */
314 static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
315 struct sk_buff *skb,
316 struct iovec *iv, int len)
317 {
318 struct tun_pi pi = { 0, skb->protocol };
319 ssize_t total = 0;
321 if (!(tun->flags & TUN_NO_PI)) {
322 if ((len -= sizeof(pi)) < 0)
323 return -EINVAL;
325 if (len < skb->len) {
326 /* Packet will be striped */
327 pi.flags |= TUN_PKT_STRIP;
328 }
330 if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
331 return -EFAULT;
332 total += sizeof(pi);
333 }
335 len = min_t(int, skb->len, len);
337 skb_copy_datagram_iovec(skb, 0, iv, len);
338 total += len;
340 tun->stats.tx_packets++;
341 tun->stats.tx_bytes += len;
343 return total;
344 }
346 /* Readv */
347 static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
348 unsigned long count, loff_t *pos)
349 {
350 struct tun_struct *tun = file->private_data;
351 DECLARE_WAITQUEUE(wait, current);
352 struct sk_buff *skb;
353 ssize_t len, ret = 0;
355 if (!tun)
356 return -EBADFD;
358 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
360 len = iov_total(iv, count);
361 if (len < 0)
362 return -EINVAL;
364 add_wait_queue(&tun->read_wait, &wait);
365 while (len) {
366 const u8 ones[ ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
367 u8 addr[ ETH_ALEN];
368 int bit_nr;
370 current->state = TASK_INTERRUPTIBLE;
372 /* Read frames from the queue */
373 if (!(skb=skb_dequeue(&tun->readq))) {
374 if (file->f_flags & O_NONBLOCK) {
375 ret = -EAGAIN;
376 break;
377 }
378 if (signal_pending(current)) {
379 ret = -ERESTARTSYS;
380 break;
381 }
383 /* Nothing to read, let's sleep */
384 schedule();
385 continue;
386 }
387 netif_wake_queue(tun->dev);
389 /** Decide whether to accept this packet. This code is designed to
390 * behave identically to an Ethernet interface. Accept the packet if
391 * - we are promiscuous.
392 * - the packet is addressed to us.
393 * - the packet is broadcast.
394 * - the packet is multicast and
395 * - we are multicast promiscous.
396 * - we belong to the multicast group.
397 */
398 memcpy(addr, skb->data,
399 min_t(size_t, sizeof addr, skb->len));
400 bit_nr = ether_crc(sizeof addr, addr) >> 26;
401 if ((tun->if_flags & IFF_PROMISC) ||
402 memcmp(addr, tun->dev_addr, sizeof addr) == 0 ||
403 memcmp(addr, ones, sizeof addr) == 0 ||
404 (((addr[0] == 1 && addr[1] == 0 && addr[2] == 0x5e) ||
405 (addr[0] == 0x33 && addr[1] == 0x33)) &&
406 ((tun->if_flags & IFF_ALLMULTI) ||
407 (tun->chr_filter[bit_nr >> 5] & (1 << (bit_nr & 31)))))) {
408 DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %x:%x:%x:%x:%x:%x\n",
409 tun->dev->name, addr[0], addr[1], addr[2],
410 addr[3], addr[4], addr[5]);
411 ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
412 kfree_skb(skb);
413 break;
414 } else {
415 DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %x:%x:%x:%x:%x:%x\n",
416 tun->dev->name, addr[0], addr[1], addr[2],
417 addr[3], addr[4], addr[5]);
418 kfree_skb(skb);
419 continue;
420 }
421 }
423 current->state = TASK_RUNNING;
424 remove_wait_queue(&tun->read_wait, &wait);
426 return ret;
427 }
429 /* Read */
430 static ssize_t tun_chr_read(struct file * file, char __user * buf,
431 size_t count, loff_t *pos)
432 {
433 struct iovec iv = { buf, count };
434 return tun_chr_readv(file, &iv, 1, pos);
435 }
437 static void tun_setup(struct net_device *dev)
438 {
439 struct tun_struct *tun = netdev_priv(dev);
441 skb_queue_head_init(&tun->readq);
442 init_waitqueue_head(&tun->read_wait);
444 tun->owner = -1;
446 SET_MODULE_OWNER(dev);
447 dev->open = tun_net_open;
448 dev->hard_start_xmit = tun_net_xmit;
449 dev->stop = tun_net_close;
450 dev->get_stats = tun_net_stats;
451 dev->ethtool_ops = &tun_ethtool_ops;
452 dev->destructor = free_netdev;
453 }
455 static struct tun_struct *tun_get_by_name(const char *name)
456 {
457 struct tun_struct *tun;
459 ASSERT_RTNL();
460 list_for_each_entry(tun, &tun_dev_list, list) {
461 if (!strncmp(tun->dev->name, name, IFNAMSIZ))
462 return tun;
463 }
465 return NULL;
466 }
468 static int tun_set_iff(struct file *file, struct ifreq *ifr)
469 {
470 struct tun_struct *tun;
471 struct net_device *dev;
472 int err;
474 tun = tun_get_by_name(ifr->ifr_name);
475 if (tun) {
476 if (tun->attached)
477 return -EBUSY;
479 /* Check permissions */
480 if (tun->owner != -1 &&
481 current->euid != tun->owner && !capable(CAP_NET_ADMIN))
482 return -EPERM;
483 }
484 else if (__dev_get_by_name(ifr->ifr_name))
485 return -EINVAL;
486 else {
487 char *name;
488 unsigned long flags = 0;
490 err = -EINVAL;
492 if (!capable(CAP_NET_ADMIN))
493 return -EPERM;
495 /* Set dev type */
496 if (ifr->ifr_flags & IFF_TUN) {
497 /* TUN device */
498 flags |= TUN_TUN_DEV;
499 name = "tun%d";
500 } else if (ifr->ifr_flags & IFF_TAP) {
501 /* TAP device */
502 flags |= TUN_TAP_DEV;
503 name = "tap%d";
504 } else
505 goto failed;
507 if (*ifr->ifr_name)
508 name = ifr->ifr_name;
510 dev = alloc_netdev(sizeof(struct tun_struct), name,
511 tun_setup);
512 if (!dev)
513 return -ENOMEM;
515 tun = netdev_priv(dev);
516 tun->dev = dev;
517 tun->flags = flags;
518 /* Be promiscuous by default to maintain previous behaviour. */
519 tun->if_flags = IFF_PROMISC;
520 /* Generate random Ethernet address. */
521 *(u16 *)tun->dev_addr = htons(0x00FF);
522 get_random_bytes(tun->dev_addr + sizeof(u16), 4);
523 memset(tun->chr_filter, 0, sizeof tun->chr_filter);
525 tun_net_init(dev);
527 if (strchr(dev->name, '%')) {
528 err = dev_alloc_name(dev, dev->name);
529 if (err < 0)
530 goto err_free_dev;
531 }
533 err = register_netdevice(tun->dev);
534 if (err < 0)
535 goto err_free_dev;
537 list_add(&tun->list, &tun_dev_list);
538 }
540 DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
542 if (ifr->ifr_flags & IFF_NO_PI)
543 tun->flags |= TUN_NO_PI;
545 if (ifr->ifr_flags & IFF_ONE_QUEUE)
546 tun->flags |= TUN_ONE_QUEUE;
548 file->private_data = tun;
549 tun->attached = 1;
551 strcpy(ifr->ifr_name, tun->dev->name);
552 return 0;
554 err_free_dev:
555 free_netdev(dev);
556 failed:
557 return err;
558 }
560 static int tun_chr_ioctl(struct inode *inode, struct file *file,
561 unsigned int cmd, unsigned long arg)
562 {
563 struct tun_struct *tun = file->private_data;
564 void __user* argp = (void __user*)arg;
565 struct ifreq ifr;
567 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
568 if (copy_from_user(&ifr, argp, sizeof ifr))
569 return -EFAULT;
571 if (cmd == TUNSETIFF && !tun) {
572 int err;
574 ifr.ifr_name[IFNAMSIZ-1] = '\0';
576 rtnl_lock();
577 err = tun_set_iff(file, &ifr);
578 rtnl_unlock();
580 if (err)
581 return err;
583 if (copy_to_user(argp, &ifr, sizeof(ifr)))
584 return -EFAULT;
585 return 0;
586 }
588 if (!tun)
589 return -EBADFD;
591 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
593 switch (cmd) {
594 case TUNSETNOCSUM:
595 /* Disable/Enable checksum */
596 if (arg)
597 tun->flags |= TUN_NOCHECKSUM;
598 else
599 tun->flags &= ~TUN_NOCHECKSUM;
601 DBG(KERN_INFO "%s: checksum %s\n",
602 tun->dev->name, arg ? "disabled" : "enabled");
603 break;
605 case TUNSETPERSIST:
606 /* Disable/Enable persist mode */
607 if (arg)
608 tun->flags |= TUN_PERSIST;
609 else
610 tun->flags &= ~TUN_PERSIST;
612 DBG(KERN_INFO "%s: persist %s\n",
613 tun->dev->name, arg ? "disabled" : "enabled");
614 break;
616 case TUNSETOWNER:
617 /* Set owner of the device */
618 tun->owner = (uid_t) arg;
620 DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
621 break;
623 case TUNSETLINK:
624 /* Only allow setting the type when the interface is down */
625 if (tun->dev->flags & IFF_UP) {
626 DBG(KERN_INFO "%s: Linktype set failed because interface is up\n",
627 tun->dev->name);
628 return -EBUSY;
629 } else {
630 tun->dev->type = (int) arg;
631 DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type);
632 }
633 break;
635 #ifdef TUN_DEBUG
636 case TUNSETDEBUG:
637 tun->debug = arg;
638 break;
639 #endif
641 case SIOCGIFFLAGS:
642 ifr.ifr_flags = tun->if_flags;
643 if (copy_to_user( argp, &ifr, sizeof ifr))
644 return -EFAULT;
645 return 0;
647 case SIOCSIFFLAGS:
648 /** Set the character device's interface flags. Currently only
649 * IFF_PROMISC and IFF_ALLMULTI are used. */
650 tun->if_flags = ifr.ifr_flags;
651 DBG(KERN_INFO "%s: interface flags 0x%lx\n",
652 tun->dev->name, tun->if_flags);
653 return 0;
655 case SIOCGIFHWADDR:
656 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
657 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
658 if (copy_to_user( argp, &ifr, sizeof ifr))
659 return -EFAULT;
660 return 0;
662 case SIOCSIFHWADDR:
663 /** Set the character device's hardware address. This is used when
664 * filtering packets being sent from the network device to the character
665 * device. */
666 memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
667 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
668 DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n",
669 tun->dev->name,
670 tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2],
671 tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]);
672 return 0;
674 case SIOCADDMULTI:
675 /** Add the specified group to the character device's multicast filter
676 * list. */
677 add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
678 DBG(KERN_DEBUG "%s: add multi: %x:%x:%x:%x:%x:%x\n",
679 tun->dev->name,
680 (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
681 (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
682 (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
683 return 0;
685 case SIOCDELMULTI:
686 /** Remove the specified group from the character device's multicast
687 * filter list. */
688 del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
689 DBG(KERN_DEBUG "%s: del multi: %x:%x:%x:%x:%x:%x\n",
690 tun->dev->name,
691 (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
692 (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
693 (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
694 return 0;
696 default:
697 return -EINVAL;
698 };
700 return 0;
701 }
703 static int tun_chr_fasync(int fd, struct file *file, int on)
704 {
705 struct tun_struct *tun = file->private_data;
706 int ret;
708 if (!tun)
709 return -EBADFD;
711 DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
713 if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
714 return ret;
716 if (on) {
717 ret = f_setown(file, current->pid, 0);
718 if (ret)
719 return ret;
720 tun->flags |= TUN_FASYNC;
721 } else
722 tun->flags &= ~TUN_FASYNC;
724 return 0;
725 }
727 static int tun_chr_open(struct inode *inode, struct file * file)
728 {
729 DBG1(KERN_INFO "tunX: tun_chr_open\n");
730 file->private_data = NULL;
731 return 0;
732 }
734 static int tun_chr_close(struct inode *inode, struct file *file)
735 {
736 struct tun_struct *tun = file->private_data;
738 if (!tun)
739 return 0;
741 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
743 tun_chr_fasync(-1, file, 0);
745 rtnl_lock();
747 /* Detach from net device */
748 file->private_data = NULL;
749 tun->attached = 0;
751 /* Drop read queue */
752 skb_queue_purge(&tun->readq);
754 if (!(tun->flags & TUN_PERSIST)) {
755 list_del(&tun->list);
756 unregister_netdevice(tun->dev);
757 }
759 rtnl_unlock();
761 return 0;
762 }
764 static struct file_operations tun_fops = {
765 .owner = THIS_MODULE,
766 .llseek = no_llseek,
767 .read = tun_chr_read,
768 .readv = tun_chr_readv,
769 .write = tun_chr_write,
770 .writev = tun_chr_writev,
771 .poll = tun_chr_poll,
772 .ioctl = tun_chr_ioctl,
773 .open = tun_chr_open,
774 .release = tun_chr_close,
775 .fasync = tun_chr_fasync
776 };
778 static struct miscdevice tun_miscdev = {
779 .minor = TUN_MINOR,
780 .name = "tun",
781 .fops = &tun_fops,
782 };
784 /* ethtool interface */
786 static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
787 {
788 cmd->supported = 0;
789 cmd->advertising = 0;
790 cmd->speed = SPEED_10;
791 cmd->duplex = DUPLEX_FULL;
792 cmd->port = PORT_TP;
793 cmd->phy_address = 0;
794 cmd->transceiver = XCVR_INTERNAL;
795 cmd->autoneg = AUTONEG_DISABLE;
796 cmd->maxtxpkt = 0;
797 cmd->maxrxpkt = 0;
798 return 0;
799 }
801 static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
802 {
803 struct tun_struct *tun = netdev_priv(dev);
805 strcpy(info->driver, DRV_NAME);
806 strcpy(info->version, DRV_VERSION);
807 strcpy(info->fw_version, "N/A");
809 switch (tun->flags & TUN_TYPE_MASK) {
810 case TUN_TUN_DEV:
811 strcpy(info->bus_info, "tun");
812 break;
813 case TUN_TAP_DEV:
814 strcpy(info->bus_info, "tap");
815 break;
816 }
817 }
819 static u32 tun_get_msglevel(struct net_device *dev)
820 {
821 #ifdef TUN_DEBUG
822 struct tun_struct *tun = netdev_priv(dev);
823 return tun->debug;
824 #else
825 return -EOPNOTSUPP;
826 #endif
827 }
829 static void tun_set_msglevel(struct net_device *dev, u32 value)
830 {
831 #ifdef TUN_DEBUG
832 struct tun_struct *tun = netdev_priv(dev);
833 tun->debug = value;
834 #endif
835 }
837 static u32 tun_get_link(struct net_device *dev)
838 {
839 struct tun_struct *tun = netdev_priv(dev);
840 return tun->attached;
841 }
843 static u32 tun_get_rx_csum(struct net_device *dev)
844 {
845 struct tun_struct *tun = netdev_priv(dev);
846 return (tun->flags & TUN_NOCHECKSUM) == 0;
847 }
849 static int tun_set_rx_csum(struct net_device *dev, u32 data)
850 {
851 struct tun_struct *tun = netdev_priv(dev);
852 if (data)
853 tun->flags &= ~TUN_NOCHECKSUM;
854 else
855 tun->flags |= TUN_NOCHECKSUM;
856 return 0;
857 }
859 static struct ethtool_ops tun_ethtool_ops = {
860 .get_settings = tun_get_settings,
861 .get_drvinfo = tun_get_drvinfo,
862 .get_msglevel = tun_get_msglevel,
863 .set_msglevel = tun_set_msglevel,
864 .get_link = tun_get_link,
865 .get_rx_csum = tun_get_rx_csum,
866 .set_rx_csum = tun_set_rx_csum
867 };
869 static int __init tun_init(void)
870 {
871 int ret = 0;
873 printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
874 printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
876 ret = misc_register(&tun_miscdev);
877 if (ret)
878 printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
879 return ret;
880 }
882 static void tun_cleanup(void)
883 {
884 struct tun_struct *tun, *nxt;
886 misc_deregister(&tun_miscdev);
888 rtnl_lock();
889 list_for_each_entry_safe(tun, nxt, &tun_dev_list, list) {
890 DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
891 unregister_netdevice(tun->dev);
892 }
893 rtnl_unlock();
895 }
897 module_init(tun_init);
898 module_exit(tun_cleanup);
899 MODULE_DESCRIPTION(DRV_DESCRIPTION);
900 MODULE_AUTHOR(DRV_COPYRIGHT);
901 MODULE_LICENSE("GPL");
902 MODULE_ALIAS_MISCDEV(TUN_MINOR);