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