xref: /dflybsd-src/sys/net/tun/if_tun.c (revision e6f30c11b835a7878a0ca02133e6bbb9abfad4ab)
1 /*	$NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5  * Nottingham University 1987.
6  *
7  * This source may be freely distributed, however I would be interested
8  * in any changes that are made.
9  *
10  * This driver takes packets off the IP i/f and hands them up to a
11  * user process to have its wicked way with. This driver has it's
12  * roots in a similar driver written by Phil Cockcroft (formerly) at
13  * UCL. This driver is based much more on read/write/poll mode of
14  * operation though.
15  *
16  * $FreeBSD: src/sys/net/if_tun.c,v 1.74.2.8 2002/02/13 00:43:11 dillon Exp $
17  * $DragonFly: src/sys/net/tun/if_tun.c,v 1.22 2005/06/14 20:41:24 joerg Exp $
18  */
19 
20 #include "opt_atalk.h"
21 #include "opt_inet.h"
22 #include "opt_inet6.h"
23 #include "opt_ipx.h"
24 
25 #include <sys/param.h>
26 #include <sys/proc.h>
27 #include <sys/systm.h>
28 #include <sys/mbuf.h>
29 #include <sys/socket.h>
30 #include <sys/filio.h>
31 #include <sys/sockio.h>
32 #include <sys/thread2.h>
33 #include <sys/ttycom.h>
34 #include <sys/poll.h>
35 #include <sys/signalvar.h>
36 #include <sys/filedesc.h>
37 #include <sys/kernel.h>
38 #include <sys/sysctl.h>
39 #include <sys/conf.h>
40 #include <sys/uio.h>
41 #include <sys/vnode.h>
42 #include <sys/malloc.h>
43 
44 #include <net/if.h>
45 #include <net/if_types.h>
46 #include <net/ifq_var.h>
47 #include <net/netisr.h>
48 #include <net/route.h>
49 
50 #ifdef INET
51 #include <netinet/in.h>
52 #endif
53 
54 #include <net/bpf.h>
55 
56 #include "if_tunvar.h"
57 #include "if_tun.h"
58 
59 static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface");
60 
61 static void tunattach (void *);
62 PSEUDO_SET(tunattach, if_tun);
63 
64 static void tuncreate (dev_t dev);
65 
66 #define TUNDEBUG	if (tundebug) if_printf
67 static int tundebug = 0;
68 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
69 
70 static int tunoutput (struct ifnet *, struct mbuf *, struct sockaddr *,
71 	    struct rtentry *rt);
72 static int tunifioctl (struct ifnet *, u_long, caddr_t, struct ucred *);
73 static int tuninit (struct ifnet *);
74 static void tunstart(struct ifnet *);
75 
76 static	d_open_t	tunopen;
77 static	d_close_t	tunclose;
78 static	d_read_t	tunread;
79 static	d_write_t	tunwrite;
80 static	d_ioctl_t	tunioctl;
81 static	d_poll_t	tunpoll;
82 
83 #define CDEV_MAJOR 52
84 static struct cdevsw tun_cdevsw = {
85 	/* name */	"tun",
86 	/* maj */	CDEV_MAJOR,
87 	/* flags */	0,
88 	/* port */	NULL,
89 	/* clone */	NULL,
90 
91 	/* open */	tunopen,
92 	/* close */	tunclose,
93 	/* read */	tunread,
94 	/* write */	tunwrite,
95 	/* ioctl */	tunioctl,
96 	/* poll */	tunpoll,
97 	/* mmap */	nommap,
98 	/* strategy */	nostrategy,
99 	/* dump */	nodump,
100 	/* psize */	nopsize
101 };
102 
103 static void
104 tunattach(void *dummy)
105 {
106 	cdevsw_add(&tun_cdevsw, 0, 0);
107 }
108 
109 static void
110 tuncreate(dev)
111 	dev_t dev;
112 {
113 	struct tun_softc *sc;
114 	struct ifnet *ifp;
115 
116 	dev = make_dev(&tun_cdevsw, minor(dev),
117 	    UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
118 
119 	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK);
120 	bzero(sc, sizeof *sc);
121 	sc->tun_flags = TUN_INITED;
122 
123 	ifp = &sc->tun_if;
124 	if_initname(ifp, "tun", lminor(dev));
125 	ifp->if_mtu = TUNMTU;
126 	ifp->if_ioctl = tunifioctl;
127 	ifp->if_output = tunoutput;
128 	ifp->if_start = tunstart;
129 	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
130 	ifp->if_type = IFT_PPP;
131 	ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
132 	ifq_set_ready(&ifp->if_snd);
133 	ifp->if_softc = sc;
134 	if_attach(ifp);
135 	bpfattach(ifp, DLT_NULL, sizeof(u_int));
136 	dev->si_drv1 = sc;
137 }
138 
139 /*
140  * tunnel open - must be superuser & the device must be
141  * configured in
142  */
143 static	int
144 tunopen(dev_t dev, int flag, int mode, struct thread *td)
145 {
146 	struct ifnet	*ifp;
147 	struct tun_softc *tp;
148 	int	error;
149 
150 	KKASSERT(td->td_proc);
151 	if ((error = suser(td)) != NULL)
152 		return (error);
153 
154 	tp = dev->si_drv1;
155 	if (!tp) {
156 		tuncreate(dev);
157 		tp = dev->si_drv1;
158 	}
159 	if (tp->tun_flags & TUN_OPEN)
160 		return EBUSY;
161 	tp->tun_pid = td->td_proc->p_pid;
162 	ifp = &tp->tun_if;
163 	tp->tun_flags |= TUN_OPEN;
164 	TUNDEBUG(ifp, "open\n");
165 	return (0);
166 }
167 
168 /*
169  * tunclose - close the device - mark i/f down & delete
170  * routing info
171  */
172 static	int
173 tunclose(dev_t dev, int foo, int bar, struct thread *td)
174 {
175 	struct tun_softc *tp;
176 	struct ifnet	*ifp;
177 
178 	tp = dev->si_drv1;
179 	ifp = &tp->tun_if;
180 
181 	tp->tun_flags &= ~TUN_OPEN;
182 	tp->tun_pid = 0;
183 
184 	/* Junk all pending output. */
185 	crit_enter();
186 	ifq_purge(&ifp->if_snd);
187 	crit_exit();
188 
189 	if (ifp->if_flags & IFF_UP) {
190 		crit_enter();
191 		if_down(ifp);
192 		crit_exit();
193 	}
194 
195 	if (ifp->if_flags & IFF_RUNNING) {
196 		struct ifaddr *ifa;
197 
198 		crit_enter();
199 		/* find internet addresses and delete routes */
200 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
201 			if (ifa->ifa_addr->sa_family == AF_INET)
202 				rtinit(ifa, (int)RTM_DELETE,
203 				    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
204 		ifp->if_flags &= ~IFF_RUNNING;
205 		crit_exit();
206 	}
207 
208 	funsetown(tp->tun_sigio);
209 	selwakeup(&tp->tun_rsel);
210 
211 	TUNDEBUG(ifp, "closed\n");
212 	return (0);
213 }
214 
215 static int
216 tuninit(ifp)
217 	struct ifnet *ifp;
218 {
219 	struct tun_softc *tp = ifp->if_softc;
220 	struct ifaddr *ifa;
221 	int error = 0;
222 
223 	TUNDEBUG(ifp, "tuninit\n");
224 
225 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
226 	getmicrotime(&ifp->if_lastchange);
227 
228 	for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
229 	     ifa = TAILQ_NEXT(ifa, ifa_link)) {
230 		if (ifa->ifa_addr == NULL)
231 			error = EFAULT;
232 			/* XXX: Should maybe return straight off? */
233 		else {
234 #ifdef INET
235 			if (ifa->ifa_addr->sa_family == AF_INET) {
236 			    struct sockaddr_in *si;
237 
238 			    si = (struct sockaddr_in *)ifa->ifa_addr;
239 			    if (si->sin_addr.s_addr)
240 				    tp->tun_flags |= TUN_IASET;
241 
242 			    si = (struct sockaddr_in *)ifa->ifa_dstaddr;
243 			    if (si && si->sin_addr.s_addr)
244 				    tp->tun_flags |= TUN_DSTADDR;
245 			}
246 #endif
247 		}
248 	}
249 	return (error);
250 }
251 
252 /*
253  * Process an ioctl request.
254  */
255 int
256 tunifioctl(ifp, cmd, data, cr)
257 	struct ifnet *ifp;
258 	u_long	cmd;
259 	caddr_t	data;
260 	struct ucred *cr;
261 {
262 	struct ifreq *ifr = (struct ifreq *)data;
263 	struct tun_softc *tp = ifp->if_softc;
264 	struct ifstat *ifs;
265 	int error = 0;
266 
267 	crit_enter();
268 
269 	switch(cmd) {
270 	case SIOCGIFSTATUS:
271 		ifs = (struct ifstat *)data;
272 		if (tp->tun_pid)
273 			sprintf(ifs->ascii + strlen(ifs->ascii),
274 			    "\tOpened by PID %d\n", tp->tun_pid);
275 		break;
276 	case SIOCSIFADDR:
277 		error = tuninit(ifp);
278 		TUNDEBUG(ifp, "address set, error=%d\n", error);
279 		break;
280 	case SIOCSIFDSTADDR:
281 		error = tuninit(ifp);
282 		TUNDEBUG(ifp, "destination address set, error=%d\n", error);
283 		break;
284 	case SIOCSIFMTU:
285 		ifp->if_mtu = ifr->ifr_mtu;
286 		TUNDEBUG(ifp, "mtu set\n");
287 		break;
288 	case SIOCSIFFLAGS:
289 	case SIOCADDMULTI:
290 	case SIOCDELMULTI:
291 		break;
292 	default:
293 		error = EINVAL;
294 	}
295 
296 	crit_exit();
297 	return (error);
298 }
299 
300 /*
301  * tunoutput - queue packets from higher level ready to put out.
302  */
303 int
304 tunoutput(ifp, m0, dst, rt)
305 	struct ifnet   *ifp;
306 	struct mbuf    *m0;
307 	struct sockaddr *dst;
308 	struct rtentry *rt;
309 {
310 	struct tun_softc *tp = ifp->if_softc;
311 	int error;
312 	struct altq_pktattr pktattr;
313 
314 	TUNDEBUG(ifp, "tunoutput\n");
315 
316 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
317 		TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags);
318 		m_freem (m0);
319 		return EHOSTDOWN;
320 	}
321 
322 	/*
323 	 * if the queueing discipline needs packet classification,
324 	 * do it before prepending link headers.
325 	 */
326 	ifq_classify(&ifp->if_snd, m0, dst->sa_family, &pktattr);
327 
328 	/* BPF write needs to be handled specially */
329 	if (dst->sa_family == AF_UNSPEC) {
330 		dst->sa_family = *(mtod(m0, int *));
331 		m0->m_len -= sizeof(int);
332 		m0->m_pkthdr.len -= sizeof(int);
333 		m0->m_data += sizeof(int);
334 	}
335 
336 	if (ifp->if_bpf) {
337 		/*
338 		 * We need to prepend the address family as
339 		 * a four byte field.
340 		 */
341 		uint32_t af = dst->sa_family;
342 
343 		bpf_ptap(ifp->if_bpf, m0, &af, sizeof(af));
344 	}
345 
346 	/* prepend sockaddr? this may abort if the mbuf allocation fails */
347 	if (tp->tun_flags & TUN_LMODE) {
348 		/* allocate space for sockaddr */
349 		M_PREPEND(m0, dst->sa_len, MB_DONTWAIT);
350 
351 		/* if allocation failed drop packet */
352 		if (m0 == NULL){
353 			crit_enter();
354 			IF_DROP(&ifp->if_snd);
355 			crit_exit();
356 			ifp->if_oerrors++;
357 			return (ENOBUFS);
358 		} else {
359 			bcopy(dst, m0->m_data, dst->sa_len);
360 		}
361 	}
362 
363 	if (tp->tun_flags & TUN_IFHEAD) {
364 		/* Prepend the address family */
365 		M_PREPEND(m0, 4, MB_DONTWAIT);
366 
367 		/* if allocation failed drop packet */
368 		if (m0 == NULL){
369 			crit_enter();
370 			IF_DROP(&ifp->if_snd);
371 			crit_exit();
372 			ifp->if_oerrors++;
373 			return ENOBUFS;
374 		} else
375 			*(u_int32_t *)m0->m_data = htonl(dst->sa_family);
376 	} else {
377 #ifdef INET
378 		if (dst->sa_family != AF_INET)
379 #endif
380 		{
381 			m_freem(m0);
382 			return EAFNOSUPPORT;
383 		}
384 	}
385 
386 	error = ifq_handoff(ifp, m0, &pktattr);
387 	if (error)
388 		ifp->if_collisions++;
389 	else
390 		ifp->if_opackets++;
391 	return (error);
392 }
393 
394 /*
395  * the cdevsw interface is now pretty minimal.
396  */
397 static	int
398 tunioctl(dev_t	dev, u_long cmd, caddr_t data, int flag, struct thread *td)
399 {
400 	struct tun_softc *tp = dev->si_drv1;
401  	struct tuninfo *tunp;
402 
403 	switch (cmd) {
404  	case TUNSIFINFO:
405  		tunp = (struct tuninfo *)data;
406 		if (tunp->mtu < IF_MINMTU)
407 			return (EINVAL);
408  		tp->tun_if.if_mtu = tunp->mtu;
409  		tp->tun_if.if_type = tunp->type;
410  		tp->tun_if.if_baudrate = tunp->baudrate;
411  		break;
412  	case TUNGIFINFO:
413  		tunp = (struct tuninfo *)data;
414  		tunp->mtu = tp->tun_if.if_mtu;
415  		tunp->type = tp->tun_if.if_type;
416  		tunp->baudrate = tp->tun_if.if_baudrate;
417  		break;
418 	case TUNSDEBUG:
419 		tundebug = *(int *)data;
420 		break;
421 	case TUNGDEBUG:
422 		*(int *)data = tundebug;
423 		break;
424 	case TUNSLMODE:
425 		if (*(int *)data) {
426 			tp->tun_flags |= TUN_LMODE;
427 			tp->tun_flags &= ~TUN_IFHEAD;
428 		} else
429 			tp->tun_flags &= ~TUN_LMODE;
430 		break;
431 	case TUNSIFHEAD:
432 		if (*(int *)data) {
433 			tp->tun_flags |= TUN_IFHEAD;
434 			tp->tun_flags &= ~TUN_LMODE;
435 		} else
436 			tp->tun_flags &= ~TUN_IFHEAD;
437 		break;
438 	case TUNGIFHEAD:
439 		*(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
440 		break;
441 	case TUNSIFMODE:
442 		/* deny this if UP */
443 		if (tp->tun_if.if_flags & IFF_UP)
444 			return(EBUSY);
445 
446 		switch (*(int *)data & ~IFF_MULTICAST) {
447 		case IFF_POINTOPOINT:
448 		case IFF_BROADCAST:
449 			tp->tun_if.if_flags &= ~(IFF_BROADCAST|IFF_POINTOPOINT);
450 			tp->tun_if.if_flags |= *(int *)data;
451 			break;
452 		default:
453 			return(EINVAL);
454 		}
455 		break;
456 	case TUNSIFPID:
457 		tp->tun_pid = curproc->p_pid;
458 		break;
459 	case FIONBIO:
460 		break;
461 	case FIOASYNC:
462 		if (*(int *)data)
463 			tp->tun_flags |= TUN_ASYNC;
464 		else
465 			tp->tun_flags &= ~TUN_ASYNC;
466 		break;
467 	case FIONREAD:
468 		crit_enter();
469 
470 		if (!ifq_is_empty(&tp->tun_if.if_snd)) {
471 			struct mbuf *mb;
472 
473 			mb = ifq_poll(&tp->tun_if.if_snd);
474 			for( *(int *)data = 0; mb != 0; mb = mb->m_next)
475 				*(int *)data += mb->m_len;
476 		} else
477 			*(int *)data = 0;
478 
479 		crit_exit();
480 		break;
481 	case FIOSETOWN:
482 		return (fsetown(*(int *)data, &tp->tun_sigio));
483 
484 	case FIOGETOWN:
485 		*(int *)data = fgetown(tp->tun_sigio);
486 		return (0);
487 
488 	/* This is deprecated, FIOSETOWN should be used instead. */
489 	case TIOCSPGRP:
490 		return (fsetown(-(*(int *)data), &tp->tun_sigio));
491 
492 	/* This is deprecated, FIOGETOWN should be used instead. */
493 	case TIOCGPGRP:
494 		*(int *)data = -fgetown(tp->tun_sigio);
495 		return (0);
496 
497 	default:
498 		return (ENOTTY);
499 	}
500 	return (0);
501 }
502 
503 /*
504  * The cdevsw read interface - reads a packet at a time, or at
505  * least as much of a packet as can be read.
506  */
507 static	int
508 tunread(dev, uio, flag)
509 	dev_t dev;
510 	struct uio *uio;
511 	int flag;
512 {
513 	struct tun_softc *tp = dev->si_drv1;
514 	struct ifnet	*ifp = &tp->tun_if;
515 	struct mbuf	*m0;
516 	int		error=0, len;
517 
518 	TUNDEBUG(ifp, "read\n");
519 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
520 		TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags);
521 		return EHOSTDOWN;
522 	}
523 
524 	tp->tun_flags &= ~TUN_RWAIT;
525 
526 	crit_enter();
527 
528 	while ((m0 = ifq_dequeue(&ifp->if_snd)) == NULL) {
529 		if (flag & IO_NDELAY) {
530 			crit_exit();
531 			return EWOULDBLOCK;
532 		}
533 		tp->tun_flags |= TUN_RWAIT;
534 		if ((error = tsleep(tp, PCATCH, "tunread", 0)) != 0) {
535 			crit_exit();
536 			return error;
537 		}
538 	}
539 
540 	crit_exit();
541 
542 	while (m0 && uio->uio_resid > 0 && error == 0) {
543 		len = min(uio->uio_resid, m0->m_len);
544 		if (len != 0)
545 			error = uiomove(mtod(m0, caddr_t), len, uio);
546 		m0 = m_free(m0);
547 	}
548 
549 	if (m0) {
550 		TUNDEBUG(ifp, "Dropping mbuf\n");
551 		m_freem(m0);
552 	}
553 	return error;
554 }
555 
556 /*
557  * the cdevsw write interface - an atomic write is a packet - or else!
558  */
559 static	int
560 tunwrite(dev, uio, flag)
561 	dev_t dev;
562 	struct uio *uio;
563 	int flag;
564 {
565 	struct tun_softc *tp = dev->si_drv1;
566 	struct ifnet	*ifp = &tp->tun_if;
567 	struct mbuf	*top, **mp, *m;
568 	int		error=0, tlen, mlen;
569 	uint32_t	family;
570 	int		isr;
571 
572 	TUNDEBUG(ifp, "tunwrite\n");
573 
574 	if (uio->uio_resid == 0)
575 		return 0;
576 
577 	if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
578 		TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid);
579 		return EIO;
580 	}
581 	tlen = uio->uio_resid;
582 
583 	/* get a header mbuf */
584 	MGETHDR(m, MB_DONTWAIT, MT_DATA);
585 	if (m == NULL)
586 		return ENOBUFS;
587 	mlen = MHLEN;
588 
589 	top = 0;
590 	mp = &top;
591 	while (error == 0 && uio->uio_resid > 0) {
592 		m->m_len = min(mlen, uio->uio_resid);
593 		error = uiomove(mtod (m, caddr_t), m->m_len, uio);
594 		*mp = m;
595 		mp = &m->m_next;
596 		if (uio->uio_resid > 0) {
597 			MGET (m, MB_DONTWAIT, MT_DATA);
598 			if (m == 0) {
599 				error = ENOBUFS;
600 				break;
601 			}
602 			mlen = MLEN;
603 		}
604 	}
605 	if (error) {
606 		if (top)
607 			m_freem (top);
608 		ifp->if_ierrors++;
609 		return error;
610 	}
611 
612 	top->m_pkthdr.len = tlen;
613 	top->m_pkthdr.rcvif = ifp;
614 
615 	if (ifp->if_bpf) {
616 		if (tp->tun_flags & TUN_IFHEAD) {
617 			/*
618 			 * Conveniently, we already have a 4-byte address
619 			 * family prepended to our packet !
620 			 * Inconveniently, it's in the wrong byte order !
621 			 */
622 			if ((top = m_pullup(top, sizeof(family))) == NULL)
623 				return ENOBUFS;
624 			*mtod(top, u_int32_t *) =
625 			    ntohl(*mtod(top, u_int32_t *));
626 			bpf_mtap(ifp->if_bpf, top);
627 			*mtod(top, u_int32_t *) =
628 			    htonl(*mtod(top, u_int32_t *));
629 		} else {
630 			/*
631 			 * We need to prepend the address family as
632 			 * a four byte field.
633 			 */
634 			static const uint32_t af = AF_INET;
635 
636 			bpf_ptap(ifp->if_bpf, top, &af, sizeof(af));
637 		}
638 	}
639 
640 	if (tp->tun_flags & TUN_IFHEAD) {
641 		if (top->m_len < sizeof(family) &&
642 		    (top = m_pullup(top, sizeof(family))) == NULL)
643 				return ENOBUFS;
644 		family = ntohl(*mtod(top, u_int32_t *));
645 		m_adj(top, sizeof(family));
646 	} else
647 		family = AF_INET;
648 
649 	ifp->if_ibytes += top->m_pkthdr.len;
650 	ifp->if_ipackets++;
651 
652 	switch (family) {
653 #ifdef INET
654 	case AF_INET:
655 		isr = NETISR_IP;
656 		break;
657 #endif
658 #ifdef INET6
659 	case AF_INET6:
660 		isr = NETISR_IPV6;
661 		break;
662 #endif
663 #ifdef IPX
664 	case AF_IPX:
665 		isr = NETISR_IPX;
666 		break;
667 #endif
668 #ifdef NETATALK
669 	case AF_APPLETALK:
670 		isr = NETISR_ATALK2;
671 		break;
672 #endif
673 	default:
674 		m_freem(m);
675 		return (EAFNOSUPPORT);
676 	}
677 
678 	netisr_dispatch(isr, top);
679 	return (0);
680 }
681 
682 /*
683  * tunpoll - the poll interface, this is only useful on reads
684  * really. The write detect always returns true, write never blocks
685  * anyway, it either accepts the packet or drops it.
686  */
687 static	int
688 tunpoll(dev_t dev, int events, struct thread *td)
689 {
690 	struct tun_softc *tp = dev->si_drv1;
691 	struct ifnet	*ifp = &tp->tun_if;
692 	int		revents = 0;
693 
694 	TUNDEBUG(ifp, "tunpoll\n");
695 
696 	crit_enter();
697 
698 	if (events & (POLLIN | POLLRDNORM)) {
699 		if (!ifq_is_empty(&ifp->if_snd)) {
700 			TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
701 			revents |= events & (POLLIN | POLLRDNORM);
702 		} else {
703 			TUNDEBUG(ifp, "tunpoll waiting\n");
704 			selrecord(td, &tp->tun_rsel);
705 		}
706 	}
707 	if (events & (POLLOUT | POLLWRNORM))
708 		revents |= events & (POLLOUT | POLLWRNORM);
709 
710 	crit_exit();
711 
712 	return (revents);
713 }
714 
715 /*
716  * Start packet transmission on the interface.
717  * when the interface queue is rate-limited by ALTQ,
718  * if_start is needed to drain packets from the queue in order
719  * to notify readers when outgoing packets become ready.
720  */
721 static void
722 tunstart(struct ifnet *ifp)
723 {
724 	struct tun_softc *tp = ifp->if_softc;
725 	struct mbuf *m;
726 
727 	if (!ifq_is_enabled(&ifp->if_snd))
728 		return;
729 
730 	m = ifq_poll(&ifp->if_snd);
731 	if (m != NULL) {
732 		if (tp->tun_flags & TUN_RWAIT) {
733 			tp->tun_flags &= ~TUN_RWAIT;
734 			wakeup((caddr_t)tp);
735 		}
736 		if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
737 			pgsigio(tp->tun_sigio, SIGIO, 0);
738 		selwakeup(&tp->tun_rsel);
739 	}
740 }
741