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