xref: /openbsd-src/sys/net/if_tun.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*	$OpenBSD: if_tun.c,v 1.40 2001/12/10 06:10:53 jason Exp $	*/
2 /*	$NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $	*/
3 
4 /*
5  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
6  * Nottingham University 1987.
7  *
8  * This source may be freely distributed, however I would be interested
9  * in any changes that are made.
10  *
11  * This driver takes packets off the IP i/f and hands them up to a
12  * user process to have its wicked way with. This driver has its
13  * roots in a similar driver written by Phil Cockcroft (formerly) at
14  * UCL. This driver is based much more on read/write/select mode of
15  * operation though.
16  */
17 
18 /* #define	TUN_DEBUG	9 */
19 
20 #include <sys/param.h>
21 #include <sys/kernel.h>
22 #include <sys/proc.h>
23 #include <sys/systm.h>
24 #include <sys/mbuf.h>
25 #include <sys/protosw.h>
26 #include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #include <sys/errno.h>
29 #include <sys/syslog.h>
30 #include <sys/select.h>
31 #include <sys/file.h>
32 #include <sys/time.h>
33 #include <sys/device.h>
34 #include <sys/vnode.h>
35 #include <sys/signalvar.h>
36 #include <sys/conf.h>
37 
38 #include <machine/cpu.h>
39 
40 #include <net/if.h>
41 #include <net/if_types.h>
42 #include <net/netisr.h>
43 #include <net/route.h>
44 
45 #ifdef INET
46 #include <netinet/in.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/in_var.h>
49 #include <netinet/ip.h>
50 /* #include <netinet/if_ether.h> */
51 #endif
52 
53 #ifdef NS
54 #include <netns/ns.h>
55 #include <netns/ns_if.h>
56 #endif
57 
58 #ifdef IPX
59 #include <netipx/ipx.h>
60 #include <netipx/ipx_if.h>
61 #endif
62 
63 #ifdef NETATALK
64 #include <netatalk/at.h>
65 #include <netatalk/at_var.h>
66 #endif
67 
68 #ifdef ISO
69 #include <netiso/iso.h>
70 #include <netiso/iso_var.h>
71 #endif
72 
73 #include "bpfilter.h"
74 #if NBPFILTER > 0
75 #include <net/bpf.h>
76 #endif
77 
78 #include <net/if_tun.h>
79 
80 struct tun_softc {
81 	struct	ifnet tun_if;		/* the interface */
82 	u_short	tun_flags;		/* misc flags */
83 	pid_t	tun_pgid;		/* the process group - if any */
84 	uid_t	tun_siguid;		/* uid for process that set tun_pgid */
85 	uid_t	tun_sigeuid;		/* euid for process that set tun_pgid */
86 	struct	selinfo	tun_rsel;	/* read select */
87 	struct	selinfo	tun_wsel;	/* write select (not used) */
88 };
89 
90 #ifdef	TUN_DEBUG
91 int	tundebug = TUN_DEBUG;
92 #define TUNDEBUG(a)	(tundebug? printf a : 0)
93 #else
94 #define TUNDEBUG(a)	/* (tundebug? printf a : 0) */
95 #endif
96 
97 struct tun_softc *tunctl;
98 int ntun;
99 
100 extern int ifqmaxlen;
101 
102 void	tunattach __P((int));
103 int	tunopen	__P((dev_t, int, int, struct proc *));
104 int	tunclose __P((dev_t, int, int, struct proc *));
105 int	tun_ioctl __P((struct ifnet *, u_long, caddr_t));
106 int	tun_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
107 		        struct rtentry *rt));
108 int	tunioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
109 int	tunread	__P((dev_t, struct uio *, int));
110 int	tunwrite __P((dev_t, struct uio *, int));
111 int	tunselect __P((dev_t, int, struct proc *));
112 
113 
114 static int tuninit __P((struct tun_softc *));
115 #ifdef ALTQ
116 static void tunstart __P((struct ifnet *));
117 #endif
118 
119 void
120 tunattach(n)
121 	int n;
122 {
123 	register int i;
124 	struct ifnet *ifp;
125 
126 	ntun = n;
127 	tunctl = malloc(ntun * sizeof(*tunctl), M_DEVBUF, M_WAITOK);
128 	bzero(tunctl, ntun * sizeof(*tunctl));
129 	for (i = 0; i < ntun; i++) {
130 		tunctl[i].tun_flags = TUN_INITED;
131 
132 		ifp = &tunctl[i].tun_if;
133 		sprintf(ifp->if_xname, "tun%d", i);
134 		ifp->if_softc = &tunctl[i];
135 		ifp->if_mtu = TUNMTU;
136 		ifp->if_ioctl = tun_ioctl;
137 		ifp->if_output = tun_output;
138 #ifdef ALTQ
139 		ifp->if_start = tunstart;
140 #endif
141 		ifp->if_flags = IFF_POINTOPOINT;
142 		ifp->if_type  = IFT_PROPVIRTUAL;
143 		IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
144 		IFQ_SET_READY(&ifp->if_snd);
145 		ifp->if_hdrlen = sizeof(u_int32_t);
146 		ifp->if_collisions = 0;
147 		ifp->if_ierrors = 0;
148 		ifp->if_oerrors = 0;
149 		ifp->if_ipackets = 0;
150 		ifp->if_opackets = 0;
151 		ifp->if_ibytes = 0;
152 		ifp->if_obytes = 0;
153 		if_attach(ifp);
154 #if NBPFILTER > 0
155 		bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
156 #endif
157 	}
158 }
159 
160 /*
161  * tunnel open - must be superuser & the device must be
162  * configured in
163  */
164 int
165 tunopen(dev, flag, mode, p)
166 	dev_t	dev;
167 	int	flag, mode;
168 	struct proc *p;
169 {
170 	struct tun_softc *tp;
171 	struct ifnet	*ifp;
172 	register int	unit, error;
173 
174 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
175 		return (error);
176 
177 	if ((unit = minor(dev)) >= ntun)
178 		return (ENXIO);
179 
180 	tp = &tunctl[unit];
181 	if (tp->tun_flags & TUN_OPEN)
182 		return EBUSY;
183 
184 	ifp = &tp->tun_if;
185 	tp->tun_flags |= TUN_OPEN;
186 	TUNDEBUG(("%s: open\n", ifp->if_xname));
187 	return (0);
188 }
189 
190 /*
191  * tunclose - close the device; if closing the real device, flush pending
192  *  output and (unless set STAYUP) bring down the interface.
193  */
194 int
195 tunclose(dev, flag, mode, p)
196 	dev_t	dev;
197 	int	flag;
198 	int	mode;
199 	struct proc *p;
200 {
201 	register int	unit, s;
202 	struct tun_softc *tp;
203 	struct ifnet	*ifp;
204 
205 	if ((unit = minor(dev)) >= ntun)
206 		return (ENXIO);
207 
208 	tp = &tunctl[unit];
209 	ifp = &tp->tun_if;
210 	tp->tun_flags &= ~TUN_OPEN;
211 
212 	/*
213 	 * junk all pending output
214 	 */
215 	s = splimp();
216 	IFQ_PURGE(&ifp->if_snd);
217 	splx(s);
218 
219 	if ((ifp->if_flags & IFF_UP) && !(tp->tun_flags & TUN_STAYUP)) {
220 		s = splimp();
221 		if_down(ifp);
222 		if (ifp->if_flags & IFF_RUNNING) {
223 			/* find internet addresses and delete routes */
224 			register struct ifaddr *ifa;
225 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
226 #ifdef INET
227 				if (ifa->ifa_addr->sa_family == AF_INET) {
228 					rtinit(ifa, (int)RTM_DELETE,
229 					       (tp->tun_flags & TUN_DSTADDR)?
230 							RTF_HOST : 0);
231 				}
232 #endif
233 			}
234 		}
235 		splx(s);
236 	}
237 	tp->tun_pgid = 0;
238 	selwakeup(&tp->tun_rsel);
239 
240 	TUNDEBUG(("%s: closed\n", ifp->if_xname));
241 	return (0);
242 }
243 
244 static int
245 tuninit(tp)
246 	struct tun_softc *tp;
247 {
248 	struct ifnet	*ifp = &tp->tun_if;
249 	register struct ifaddr *ifa;
250 
251 	TUNDEBUG(("%s: tuninit\n", ifp->if_xname));
252 
253 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
254 
255 	tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR|TUN_BRDADDR);
256 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
257 #ifdef INET
258 		if (ifa->ifa_addr->sa_family == AF_INET) {
259 			struct sockaddr_in *sin;
260 
261 			sin = satosin(ifa->ifa_addr);
262 			if (sin && sin->sin_addr.s_addr)
263 				tp->tun_flags |= TUN_IASET;
264 
265 			if (ifp->if_flags & IFF_POINTOPOINT) {
266 				sin = satosin(ifa->ifa_dstaddr);
267 				if (sin && sin->sin_addr.s_addr)
268 					tp->tun_flags |= TUN_DSTADDR;
269 			} else
270 				tp->tun_flags &= ~TUN_DSTADDR;
271 
272 			if (ifp->if_flags & IFF_BROADCAST) {
273 				sin = satosin(ifa->ifa_broadaddr);
274 				if (sin && sin->sin_addr.s_addr)
275 					tp->tun_flags |= TUN_BRDADDR;
276 			} else
277 				tp->tun_flags &= ~TUN_BRDADDR;
278 		}
279 #endif
280 	}
281 
282 	return 0;
283 }
284 
285 /*
286  * Process an ioctl request.
287  */
288 int
289 tun_ioctl(ifp, cmd, data)
290 	struct ifnet *ifp;
291 	u_long	cmd;
292 	caddr_t	data;
293 {
294 	int	error = 0, s;
295 
296 	s = splimp();
297 	switch(cmd) {
298 	case SIOCSIFADDR:
299 		tuninit((struct tun_softc *)(ifp->if_softc));
300 		TUNDEBUG(("%s: address set\n", ifp->if_xname));
301 		break;
302 	case SIOCSIFDSTADDR:
303 		tuninit((struct tun_softc *)(ifp->if_softc));
304 		TUNDEBUG(("%s: destination address set\n", ifp->if_xname));
305 		break;
306 	case SIOCSIFBRDADDR:
307 		tuninit((struct tun_softc *)(ifp->if_softc));
308 		TUNDEBUG(("%s: broadcast address set\n", ifp->if_xname));
309 		break;
310 	case SIOCSIFMTU:
311 		ifp->if_mtu = ((struct ifreq *)data)->ifr_mtu;
312 		break;
313 	case SIOCADDMULTI:
314 	case SIOCDELMULTI: {
315 		struct ifreq *ifr = (struct ifreq *)data;
316 		if (ifr == 0) {
317 			error = EAFNOSUPPORT;	   /* XXX */
318 			break;
319 		}
320 		switch (ifr->ifr_addr.sa_family) {
321 #ifdef INET
322 		case AF_INET:
323 			break;
324 #endif
325 #ifdef INET6
326 		case AF_INET6:
327 			break;
328 #endif
329 		default:
330 			error = EAFNOSUPPORT;
331 			break;
332 		}
333 		break;
334 	}
335 
336 	case SIOCSIFFLAGS:
337 		break;
338 	default:
339 		error = EINVAL;
340 	}
341 	splx(s);
342 	return (error);
343 }
344 
345 /*
346  * tun_output - queue packets from higher level ready to put out.
347  */
348 int
349 tun_output(ifp, m0, dst, rt)
350 	struct ifnet   *ifp;
351 	struct mbuf    *m0;
352 	struct sockaddr *dst;
353 	struct rtentry *rt;
354 {
355 	struct tun_softc *tp = ifp->if_softc;
356 	int		s, len, error;
357 	u_int32_t	*af;
358 	ALTQ_DECL(struct altq_pktattr pktattr;)
359 
360 	TUNDEBUG(("%s: tun_output\n", ifp->if_xname));
361 
362 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
363 		TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname,
364 			  tp->tun_flags));
365 		m_freem (m0);
366 		return EHOSTDOWN;
367 	}
368 
369 	/*
370 	 * if the queueing discipline needs packet classification,
371 	 * do it before prepending link headers.
372 	 */
373 	IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr);
374 
375 	M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
376 	af = mtod(m0, u_int32_t *);
377 	*af = htonl(dst->sa_family);
378 
379 #if NBPFILTER > 0
380 	if (ifp->if_bpf)
381 		bpf_mtap(ifp->if_bpf, m0);
382 #endif
383 
384 	len = m0->m_pkthdr.len + sizeof(*af);
385 	s = splimp();
386 	IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error);
387 	if (error) {
388 		splx(s);
389 		ifp->if_collisions++;
390 		return (error);
391 	}
392 	splx(s);
393 	ifp->if_opackets++;
394 	ifp->if_obytes += len;
395 
396 	if (tp->tun_flags & TUN_RWAIT) {
397 		tp->tun_flags &= ~TUN_RWAIT;
398 		wakeup((caddr_t)tp);
399 	}
400 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
401 		csignal(tp->tun_pgid, SIGIO,
402 		    tp->tun_siguid, tp->tun_sigeuid);
403 	selwakeup(&tp->tun_rsel);
404 	return 0;
405 }
406 
407 /*
408  * the cdevsw interface is now pretty minimal.
409  */
410 int
411 tunioctl(dev, cmd, data, flag, p)
412 	dev_t		dev;
413 	u_long		cmd;
414 	caddr_t		data;
415 	int		flag;
416 	struct proc	*p;
417 {
418 	int		unit, s;
419 	struct tun_softc *tp;
420 	struct tuninfo *tunp;
421 
422 	if ((unit = minor(dev)) >= ntun)
423 		return (ENXIO);
424 
425 	tp = &tunctl[unit];
426 
427 	s = splimp();
428 	switch (cmd) {
429 	case TUNSIFINFO:
430 		tunp = (struct tuninfo *)data;
431 		tp->tun_if.if_mtu = tunp->mtu;
432 		tp->tun_if.if_type = tunp->type;
433 		tp->tun_if.if_flags = tunp->flags;
434 		tp->tun_if.if_baudrate = tunp->baudrate;
435 		break;
436 	case TUNGIFINFO:
437 		tunp = (struct tuninfo *)data;
438 		tunp->mtu = tp->tun_if.if_mtu;
439 		tunp->type = tp->tun_if.if_type;
440 		tunp->flags = tp->tun_if.if_flags;
441 		tunp->baudrate = tp->tun_if.if_baudrate;
442 		break;
443 #ifdef TUN_DEBUG
444 	case TUNSDEBUG:
445 		tundebug = *(int *)data;
446 		break;
447 	case TUNGDEBUG:
448 		*(int *)data = tundebug;
449 		break;
450 #endif
451         case TUNSIFMODE:
452 	        switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
453                 case IFF_POINTOPOINT:
454                 case IFF_BROADCAST:
455                         if (tp->tun_if.if_flags & IFF_UP) {
456                                 splx(s);
457                                 return (EBUSY);
458                         }
459                         tp->tun_if.if_flags &=
460                                 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
461                         tp->tun_if.if_flags |= *(int *)data;
462                         break;
463                 default:
464 		        splx(s);
465                         return (EINVAL);
466                 }
467                 break;
468 
469        	case FIONBIO:
470 		if (*(int *)data)
471 			tp->tun_flags |= TUN_NBIO;
472 		else
473 			tp->tun_flags &= ~TUN_NBIO;
474 		break;
475 	case FIOASYNC:
476 		if (*(int *)data)
477 			tp->tun_flags |= TUN_ASYNC;
478 		else
479 			tp->tun_flags &= ~TUN_ASYNC;
480 		break;
481 	case FIONREAD:
482 		if (tp->tun_if.if_snd.ifq_head)
483 			*(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len;
484 		else
485 			*(int *)data = 0;
486 		break;
487 	case TIOCSPGRP:
488 		tp->tun_pgid = *(int *)data;
489 		tp->tun_siguid = p->p_cred->p_ruid;
490 		tp->tun_sigeuid = p->p_ucred->cr_uid;
491 		break;
492 	case TIOCGPGRP:
493 		*(int *)data = tp->tun_pgid;
494 		break;
495 	default:
496 		splx(s);
497 		return (ENOTTY);
498 	}
499 	splx(s);
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 int
508 tunread(dev, uio, ioflag)
509 	dev_t		dev;
510 	struct uio	*uio;
511 	int		ioflag;
512 {
513 	int		unit;
514 	struct tun_softc *tp;
515 	struct ifnet	*ifp;
516 	struct mbuf	*m, *m0;
517 	int		error = 0, len, s;
518 
519 	if ((unit = minor(dev)) >= ntun)
520 		return (ENXIO);
521 
522 	tp = &tunctl[unit];
523 	ifp = &tp->tun_if;
524 	TUNDEBUG(("%s: read\n", ifp->if_xname));
525 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
526 		TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname,
527 			  tp->tun_flags));
528 		return EHOSTDOWN;
529 	}
530 
531 	tp->tun_flags &= ~TUN_RWAIT;
532 
533 	s = splimp();
534 	do {
535 		while ((tp->tun_flags & TUN_READY) != TUN_READY)
536 			if ((error = tsleep((caddr_t)tp,
537 			    (PZERO+1)|PCATCH, "tunread", 0)) != 0) {
538 				splx(s);
539 				return (error);
540 			}
541 		IFQ_DEQUEUE(&ifp->if_snd, m0);
542 		if (m0 == 0) {
543 			if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) {
544 				splx(s);
545 				return EWOULDBLOCK;
546 			}
547 			tp->tun_flags |= TUN_RWAIT;
548 			if ((error = tsleep((caddr_t)tp,
549 			    (PZERO + 1)|PCATCH, "tunread", 0)) != 0) {
550 				splx(s);
551 				return (error);
552 			}
553 		}
554 	} while (m0 == 0);
555 	splx(s);
556 
557 	while (m0 && uio->uio_resid > 0 && error == 0) {
558 		len = min(uio->uio_resid, m0->m_len);
559 		if (len != 0)
560 			error = uiomove(mtod(m0, caddr_t), len, uio);
561 		MFREE(m0, m);
562 		m0 = m;
563 	}
564 
565 	if (m0) {
566 		TUNDEBUG(("Dropping mbuf\n"));
567 		m_freem(m0);
568 	}
569 	if (error)
570 		ifp->if_ierrors++;
571 
572 	return error;
573 }
574 
575 /*
576  * the cdevsw write interface - an atomic write is a packet - or else!
577  */
578 int
579 tunwrite(dev, uio, ioflag)
580 	dev_t		dev;
581 	struct uio	*uio;
582 	int		ioflag;
583 {
584 	int		unit;
585 	struct ifnet	*ifp;
586 	struct ifqueue	*ifq;
587 	u_int32_t	*th;
588 	struct mbuf	*top, **mp, *m;
589 	int		isr;
590 	int		error=0, s, tlen, mlen;
591 
592 	if ((unit = minor(dev)) >= ntun)
593 		return (ENXIO);
594 
595 	ifp = &tunctl[unit].tun_if;
596 	TUNDEBUG(("%s: tunwrite\n", ifp->if_xname));
597 
598 	if (uio->uio_resid == 0 || uio->uio_resid > TUNMRU) {
599 		TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid));
600 		return EMSGSIZE;
601 	}
602 	tlen = uio->uio_resid;
603 
604 	/* get a header mbuf */
605 	MGETHDR(m, M_DONTWAIT, MT_DATA);
606 	if (m == NULL)
607 		return ENOBUFS;
608 	mlen = MHLEN;
609 
610 	top = 0;
611 	mp = &top;
612 	while (error == 0 && uio->uio_resid > 0) {
613 		m->m_len = min(mlen, uio->uio_resid);
614 		error = uiomove(mtod (m, caddr_t), m->m_len, uio);
615 		*mp = m;
616 		mp = &m->m_next;
617 		if (uio->uio_resid > 0) {
618 			MGET (m, M_DONTWAIT, MT_DATA);
619 			if (m == 0) {
620 				error = ENOBUFS;
621 				break;
622 			}
623 			mlen = MLEN;
624 		}
625 	}
626 	if (error) {
627 		if (top)
628 			m_freem (top);
629 		ifp->if_ierrors++;
630 		return error;
631 	}
632 
633 	top->m_pkthdr.len = tlen;
634 	top->m_pkthdr.rcvif = ifp;
635 
636 #if NBPFILTER > 0
637 	if (ifp->if_bpf)
638 		bpf_mtap(ifp->if_bpf, top);
639 #endif
640 
641 	th = mtod(top, u_int32_t *);
642 	/* strip the tunnel header */
643 	top->m_data += sizeof(*th);
644 	top->m_len  -= sizeof(*th);
645 	top->m_pkthdr.len -= sizeof(*th);
646 
647 	switch (ntohl(*th)) {
648 #ifdef INET
649 	case AF_INET:
650 		ifq = &ipintrq;
651 		isr = NETISR_IP;
652 		break;
653 #endif
654 #ifdef INET6
655 	case AF_INET6:
656 		ifq = &ip6intrq;
657 		isr = NETISR_IPV6;
658 		break;
659 #endif
660 #ifdef NS
661 	case AF_NS:
662 		ifq = &nsintrq;
663 		isr = NETISR_NS;
664 		break;
665 #endif
666 #ifdef IPX
667 	case AF_IPX:
668 		ifq = &ipxintrq;
669 		isr = NETISR_IPX;
670 		break;
671 #endif
672 #ifdef NETATALK
673 	case AF_APPLETALK:
674 		ifq = &atintrq2;
675 		isr = NETISR_ATALK;
676 		break;
677 #endif
678 #ifdef ISO
679 	case AF_ISO:
680 		ifq = &clnlintrq;
681 		isr = NETISR_ISO;
682 		break;
683 #endif
684 	default:
685 		m_freem(top);
686 		return EAFNOSUPPORT;
687 	}
688 
689 	s = splimp();
690 	if (IF_QFULL(ifq)) {
691 		IF_DROP(ifq);
692 		splx(s);
693 		ifp->if_collisions++;
694 		m_freem(top);
695 		return ENOBUFS;
696 	}
697 	IF_ENQUEUE(ifq, top);
698 	schednetisr(isr);
699 	ifp->if_ipackets++;
700 	ifp->if_ibytes += top->m_pkthdr.len;
701 	splx(s);
702 	return error;
703 }
704 
705 /*
706  * tunselect - the select interface, this is only useful on reads
707  * really. The write detect always returns true, write never blocks
708  * anyway, it either accepts the packet or drops it.
709  */
710 int
711 tunselect(dev, rw, p)
712 	dev_t		dev;
713 	int		rw;
714 	struct proc	*p;
715 {
716 	int		unit, s;
717 	struct tun_softc *tp;
718 	struct ifnet	*ifp;
719 
720 	if ((unit = minor(dev)) >= ntun)
721 		return (ENXIO);
722 
723 	tp = &tunctl[unit];
724 	ifp = &tp->tun_if;
725 	s = splimp();
726 	TUNDEBUG(("%s: tunselect\n", ifp->if_xname));
727 
728 	switch (rw) {
729 	case FREAD:
730 		if (ifp->if_snd.ifq_len > 0) {
731 			splx(s);
732 			TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname,
733 				  ifp->if_snd.ifq_len));
734 			return 1;
735 		}
736 		selrecord(curproc, &tp->tun_rsel);
737 		break;
738 	case FWRITE:
739 		splx(s);
740 		return 1;
741 	}
742 	splx(s);
743 	TUNDEBUG(("%s: tunselect waiting\n", ifp->if_xname));
744 	return 0;
745 }
746 
747 #ifdef ALTQ
748 /*
749  * Start packet transmission on the interface.
750  * when the interface queue is rate-limited by ALTQ or TBR,
751  * if_start is needed to drain packets from the queue in order
752  * to notify readers when outgoing packets become ready.
753  */
754 static void
755 tunstart(ifp)
756 	struct ifnet *ifp;
757 {
758 	struct tun_softc *tp = ifp->if_softc;
759 	struct mbuf *m;
760 
761 	if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd))
762 		return;
763 
764 	IFQ_POLL(&ifp->if_snd, m);
765 	if (m != NULL) {
766 		if (tp->tun_flags & TUN_RWAIT) {
767 			tp->tun_flags &= ~TUN_RWAIT;
768 			wakeup((caddr_t)tp);
769 		}
770 		if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
771 			csignal(tp->tun_pgid, SIGIO,
772 			    tp->tun_siguid, tp->tun_sigeuid);
773 		selwakeup(&tp->tun_rsel);
774 	}
775 }
776 #endif
777