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