xref: /openbsd-src/sys/net/if_tun.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: if_tun.c,v 1.38 2001/08/03 21:13:40 itojun 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 			for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
226 			     ifa = ifa->ifa_list.tqe_next) {
227 #ifdef INET
228 				if (ifa->ifa_addr->sa_family == AF_INET) {
229 					rtinit(ifa, (int)RTM_DELETE,
230 					       (tp->tun_flags & TUN_DSTADDR)?
231 							RTF_HOST : 0);
232 				}
233 #endif
234 			}
235 		}
236 		splx(s);
237 	}
238 	tp->tun_pgid = 0;
239 	selwakeup(&tp->tun_rsel);
240 
241 	TUNDEBUG(("%s: closed\n", ifp->if_xname));
242 	return (0);
243 }
244 
245 static int
246 tuninit(tp)
247 	struct tun_softc *tp;
248 {
249 	struct ifnet	*ifp = &tp->tun_if;
250 	register struct ifaddr *ifa;
251 
252 	TUNDEBUG(("%s: tuninit\n", ifp->if_xname));
253 
254 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
255 
256 	tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR|TUN_BRDADDR);
257 	for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
258 	    ifa = ifa->ifa_list.tqe_next) {
259 #ifdef INET
260 		if (ifa->ifa_addr->sa_family == AF_INET) {
261 			struct sockaddr_in *sin;
262 
263 			sin = satosin(ifa->ifa_addr);
264 			if (sin && sin->sin_addr.s_addr)
265 				tp->tun_flags |= TUN_IASET;
266 
267 			if (ifp->if_flags & IFF_POINTOPOINT) {
268 				sin = satosin(ifa->ifa_dstaddr);
269 				if (sin && sin->sin_addr.s_addr)
270 					tp->tun_flags |= TUN_DSTADDR;
271 			} else
272 				tp->tun_flags &= ~TUN_DSTADDR;
273 
274 			if (ifp->if_flags & IFF_BROADCAST) {
275 				sin = satosin(ifa->ifa_broadaddr);
276 				if (sin && sin->sin_addr.s_addr)
277 					tp->tun_flags |= TUN_BRDADDR;
278 			} else
279 				tp->tun_flags &= ~TUN_BRDADDR;
280 		}
281 #endif
282 	}
283 
284 	return 0;
285 }
286 
287 /*
288  * Process an ioctl request.
289  */
290 int
291 tun_ioctl(ifp, cmd, data)
292 	struct ifnet *ifp;
293 	u_long	cmd;
294 	caddr_t	data;
295 {
296 	int	error = 0, s;
297 
298 	s = splimp();
299 	switch(cmd) {
300 	case SIOCSIFADDR:
301 		tuninit((struct tun_softc *)(ifp->if_softc));
302 		TUNDEBUG(("%s: address set\n", ifp->if_xname));
303 		break;
304 	case SIOCSIFDSTADDR:
305 		tuninit((struct tun_softc *)(ifp->if_softc));
306 		TUNDEBUG(("%s: destination address set\n", ifp->if_xname));
307 		break;
308 	case SIOCSIFBRDADDR:
309 		tuninit((struct tun_softc *)(ifp->if_softc));
310 		TUNDEBUG(("%s: broadcast address set\n", ifp->if_xname));
311 		break;
312 	case SIOCSIFMTU:
313 		ifp->if_mtu = ((struct ifreq *)data)->ifr_mtu;
314 		break;
315 	case SIOCSIFFLAGS:
316 		break;
317 	default:
318 		error = EINVAL;
319 	}
320 	splx(s);
321 	return (error);
322 }
323 
324 /*
325  * tun_output - queue packets from higher level ready to put out.
326  */
327 int
328 tun_output(ifp, m0, dst, rt)
329 	struct ifnet   *ifp;
330 	struct mbuf    *m0;
331 	struct sockaddr *dst;
332 	struct rtentry *rt;
333 {
334 	struct tun_softc *tp = ifp->if_softc;
335 	int		s, len, error;
336 	u_int32_t	*af;
337 	ALTQ_DECL(struct altq_pktattr pktattr;)
338 
339 	TUNDEBUG(("%s: tun_output\n", ifp->if_xname));
340 
341 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
342 		TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname,
343 			  tp->tun_flags));
344 		m_freem (m0);
345 		return EHOSTDOWN;
346 	}
347 
348 	/*
349 	 * if the queueing discipline needs packet classification,
350 	 * do it before prepending link headers.
351 	 */
352 	IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr);
353 
354 	M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
355 	af = mtod(m0, u_int32_t *);
356 	*af = htonl(dst->sa_family);
357 
358 #if NBPFILTER > 0
359 	if (ifp->if_bpf)
360 		bpf_mtap(ifp->if_bpf, m0);
361 #endif
362 
363 	len = m0->m_pkthdr.len + sizeof(*af);
364 	s = splimp();
365 	IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error);
366 	if (error) {
367 		splx(s);
368 		ifp->if_collisions++;
369 		return (error);
370 	}
371 	splx(s);
372 	ifp->if_opackets++;
373 	ifp->if_obytes += len;
374 
375 	if (tp->tun_flags & TUN_RWAIT) {
376 		tp->tun_flags &= ~TUN_RWAIT;
377 		wakeup((caddr_t)tp);
378 	}
379 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
380 		csignal(tp->tun_pgid, SIGIO,
381 		    tp->tun_siguid, tp->tun_sigeuid);
382 	selwakeup(&tp->tun_rsel);
383 	return 0;
384 }
385 
386 /*
387  * the cdevsw interface is now pretty minimal.
388  */
389 int
390 tunioctl(dev, cmd, data, flag, p)
391 	dev_t		dev;
392 	u_long		cmd;
393 	caddr_t		data;
394 	int		flag;
395 	struct proc	*p;
396 {
397 	int		unit, s;
398 	struct tun_softc *tp;
399 	struct tuninfo *tunp;
400 
401 	if ((unit = minor(dev)) >= ntun)
402 		return (ENXIO);
403 
404 	tp = &tunctl[unit];
405 
406 	s = splimp();
407 	switch (cmd) {
408 	case TUNSIFINFO:
409 		tunp = (struct tuninfo *)data;
410 		tp->tun_if.if_mtu = tunp->mtu;
411 		tp->tun_if.if_type = tunp->type;
412 		tp->tun_if.if_flags = tunp->flags;
413 		tp->tun_if.if_baudrate = tunp->baudrate;
414 		break;
415 	case TUNGIFINFO:
416 		tunp = (struct tuninfo *)data;
417 		tunp->mtu = tp->tun_if.if_mtu;
418 		tunp->type = tp->tun_if.if_type;
419 		tunp->flags = tp->tun_if.if_flags;
420 		tunp->baudrate = tp->tun_if.if_baudrate;
421 		break;
422 #ifdef TUN_DEBUG
423 	case TUNSDEBUG:
424 		tundebug = *(int *)data;
425 		break;
426 	case TUNGDEBUG:
427 		*(int *)data = tundebug;
428 		break;
429 #endif
430         case TUNSIFMODE:
431 	        switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
432                 case IFF_POINTOPOINT:
433                 case IFF_BROADCAST:
434                         if (tp->tun_if.if_flags & IFF_UP) {
435                                 splx(s);
436                                 return (EBUSY);
437                         }
438                         tp->tun_if.if_flags &=
439                                 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
440                         tp->tun_if.if_flags |= *(int *)data;
441                         break;
442                 default:
443 		        splx(s);
444                         return (EINVAL);
445                 }
446                 break;
447 
448        	case FIONBIO:
449 		if (*(int *)data)
450 			tp->tun_flags |= TUN_NBIO;
451 		else
452 			tp->tun_flags &= ~TUN_NBIO;
453 		break;
454 	case FIOASYNC:
455 		if (*(int *)data)
456 			tp->tun_flags |= TUN_ASYNC;
457 		else
458 			tp->tun_flags &= ~TUN_ASYNC;
459 		break;
460 	case FIONREAD:
461 		if (tp->tun_if.if_snd.ifq_head)
462 			*(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len;
463 		else
464 			*(int *)data = 0;
465 		break;
466 	case TIOCSPGRP:
467 		tp->tun_pgid = *(int *)data;
468 		tp->tun_siguid = p->p_cred->p_ruid;
469 		tp->tun_sigeuid = p->p_ucred->cr_uid;
470 		break;
471 	case TIOCGPGRP:
472 		*(int *)data = tp->tun_pgid;
473 		break;
474 	default:
475 		splx(s);
476 		return (ENOTTY);
477 	}
478 	splx(s);
479 	return (0);
480 }
481 
482 /*
483  * The cdevsw read interface - reads a packet at a time, or at
484  * least as much of a packet as can be read.
485  */
486 int
487 tunread(dev, uio, ioflag)
488 	dev_t		dev;
489 	struct uio	*uio;
490 	int		ioflag;
491 {
492 	int		unit;
493 	struct tun_softc *tp;
494 	struct ifnet	*ifp;
495 	struct mbuf	*m, *m0;
496 	int		error = 0, len, s;
497 
498 	if ((unit = minor(dev)) >= ntun)
499 		return (ENXIO);
500 
501 	tp = &tunctl[unit];
502 	ifp = &tp->tun_if;
503 	TUNDEBUG(("%s: read\n", ifp->if_xname));
504 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
505 		TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname,
506 			  tp->tun_flags));
507 		return EHOSTDOWN;
508 	}
509 
510 	tp->tun_flags &= ~TUN_RWAIT;
511 
512 	s = splimp();
513 	do {
514 		while ((tp->tun_flags & TUN_READY) != TUN_READY)
515 			if ((error = tsleep((caddr_t)tp,
516 			    (PZERO+1)|PCATCH, "tunread", 0)) != 0) {
517 				splx(s);
518 				return (error);
519 			}
520 		IFQ_DEQUEUE(&ifp->if_snd, m0);
521 		if (m0 == 0) {
522 			if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) {
523 				splx(s);
524 				return EWOULDBLOCK;
525 			}
526 			tp->tun_flags |= TUN_RWAIT;
527 			if ((error = tsleep((caddr_t)tp,
528 			    (PZERO + 1)|PCATCH, "tunread", 0)) != 0) {
529 				splx(s);
530 				return (error);
531 			}
532 		}
533 	} while (m0 == 0);
534 	splx(s);
535 
536 	while (m0 && uio->uio_resid > 0 && error == 0) {
537 		len = min(uio->uio_resid, m0->m_len);
538 		if (len != 0)
539 			error = uiomove(mtod(m0, caddr_t), len, uio);
540 		MFREE(m0, m);
541 		m0 = m;
542 	}
543 
544 	if (m0) {
545 		TUNDEBUG(("Dropping mbuf\n"));
546 		m_freem(m0);
547 	}
548 	if (error)
549 		ifp->if_ierrors++;
550 
551 	return error;
552 }
553 
554 /*
555  * the cdevsw write interface - an atomic write is a packet - or else!
556  */
557 int
558 tunwrite(dev, uio, ioflag)
559 	dev_t		dev;
560 	struct uio	*uio;
561 	int		ioflag;
562 {
563 	int		unit;
564 	struct ifnet	*ifp;
565 	struct ifqueue	*ifq;
566 	u_int32_t	*th;
567 	struct mbuf	*top, **mp, *m;
568 	int		isr;
569 	int		error=0, s, tlen, mlen;
570 
571 	if ((unit = minor(dev)) >= ntun)
572 		return (ENXIO);
573 
574 	ifp = &tunctl[unit].tun_if;
575 	TUNDEBUG(("%s: tunwrite\n", ifp->if_xname));
576 
577 	if (uio->uio_resid == 0 || uio->uio_resid > TUNMRU) {
578 		TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid));
579 		return EMSGSIZE;
580 	}
581 	tlen = uio->uio_resid;
582 
583 	/* get a header mbuf */
584 	MGETHDR(m, M_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, M_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 NBPFILTER > 0
616 	if (ifp->if_bpf)
617 		bpf_mtap(ifp->if_bpf, top);
618 #endif
619 
620 	th = mtod(top, u_int32_t *);
621 	/* strip the tunnel header */
622 	top->m_data += sizeof(*th);
623 	top->m_len  -= sizeof(*th);
624 	top->m_pkthdr.len -= sizeof(*th);
625 
626 	switch (ntohl(*th)) {
627 #ifdef INET
628 	case AF_INET:
629 		ifq = &ipintrq;
630 		isr = NETISR_IP;
631 		break;
632 #endif
633 #ifdef INET6
634 	case AF_INET6:
635 		ifq = &ip6intrq;
636 		isr = NETISR_IPV6;
637 		break;
638 #endif
639 #ifdef NS
640 	case AF_NS:
641 		ifq = &nsintrq;
642 		isr = NETISR_NS;
643 		break;
644 #endif
645 #ifdef IPX
646 	case AF_IPX:
647 		ifq = &ipxintrq;
648 		isr = NETISR_IPX;
649 		break;
650 #endif
651 #ifdef NETATALK
652 	case AF_APPLETALK:
653 		ifq = &atintrq2;
654 		isr = NETISR_ATALK;
655 		break;
656 #endif
657 #ifdef ISO
658 	case AF_ISO:
659 		ifq = &clnlintrq;
660 		isr = NETISR_ISO;
661 		break;
662 #endif
663 	default:
664 		m_freem(top);
665 		return EAFNOSUPPORT;
666 	}
667 
668 	s = splimp();
669 	if (IF_QFULL(ifq)) {
670 		IF_DROP(ifq);
671 		splx(s);
672 		ifp->if_collisions++;
673 		m_freem(top);
674 		return ENOBUFS;
675 	}
676 	IF_ENQUEUE(ifq, top);
677 	schednetisr(isr);
678 	ifp->if_ipackets++;
679 	ifp->if_ibytes += top->m_pkthdr.len;
680 	splx(s);
681 	return error;
682 }
683 
684 /*
685  * tunselect - the select interface, this is only useful on reads
686  * really. The write detect always returns true, write never blocks
687  * anyway, it either accepts the packet or drops it.
688  */
689 int
690 tunselect(dev, rw, p)
691 	dev_t		dev;
692 	int		rw;
693 	struct proc	*p;
694 {
695 	int		unit, s;
696 	struct tun_softc *tp;
697 	struct ifnet	*ifp;
698 
699 	if ((unit = minor(dev)) >= ntun)
700 		return (ENXIO);
701 
702 	tp = &tunctl[unit];
703 	ifp = &tp->tun_if;
704 	s = splimp();
705 	TUNDEBUG(("%s: tunselect\n", ifp->if_xname));
706 
707 	switch (rw) {
708 	case FREAD:
709 		if (ifp->if_snd.ifq_len > 0) {
710 			splx(s);
711 			TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname,
712 				  ifp->if_snd.ifq_len));
713 			return 1;
714 		}
715 		selrecord(curproc, &tp->tun_rsel);
716 		break;
717 	case FWRITE:
718 		splx(s);
719 		return 1;
720 	}
721 	splx(s);
722 	TUNDEBUG(("%s: tunselect waiting\n", ifp->if_xname));
723 	return 0;
724 }
725 
726 #ifdef ALTQ
727 /*
728  * Start packet transmission on the interface.
729  * when the interface queue is rate-limited by ALTQ or TBR,
730  * if_start is needed to drain packets from the queue in order
731  * to notify readers when outgoing packets become ready.
732  */
733 static void
734 tunstart(ifp)
735 	struct ifnet *ifp;
736 {
737 	struct tun_softc *tp = ifp->if_softc;
738 	struct mbuf *m;
739 
740 	if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd))
741 		return;
742 
743 	IFQ_POLL(&ifp->if_snd, m);
744 	if (m != NULL) {
745 		if (tp->tun_flags & TUN_RWAIT) {
746 			tp->tun_flags &= ~TUN_RWAIT;
747 			wakeup((caddr_t)tp);
748 		}
749 		if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
750 			csignal(tp->tun_pgid, SIGIO,
751 			    tp->tun_siguid, tp->tun_sigeuid);
752 		selwakeup(&tp->tun_rsel);
753 	}
754 }
755 #endif
756