if_tun.c revision 1.47 1 /* $NetBSD: if_tun.c,v 1.47 2001/11/05 18:02:16 matt Exp $ */
2
3 /*
4 * Copyright (c) 1988, Julian Onions <jpo (at) 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 its
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
17 #include "tun.h"
18 #if NTUN > 0
19
20 #include "opt_inet.h"
21 #include "opt_ns.h"
22
23 #include <sys/param.h>
24 #include <sys/proc.h>
25 #include <sys/systm.h>
26 #include <sys/mbuf.h>
27 #include <sys/buf.h>
28 #include <sys/protosw.h>
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <sys/errno.h>
32 #include <sys/syslog.h>
33 #include <sys/select.h>
34 #include <sys/poll.h>
35 #include <sys/file.h>
36 #include <sys/signalvar.h>
37 #include <sys/conf.h>
38
39 #include <machine/cpu.h>
40
41 #include <net/if.h>
42 #include <net/if_ether.h>
43 #include <net/netisr.h>
44 #include <net/route.h>
45
46
47 #ifdef INET
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/in_var.h>
51 #include <netinet/ip.h>
52 #include <netinet/if_inarp.h>
53 #endif
54
55 #ifdef NS
56 #include <netns/ns.h>
57 #include <netns/ns_if.h>
58 #endif
59
60 #include "bpfilter.h"
61 #if NBPFILTER > 0
62 #include <sys/time.h>
63 #include <net/bpf.h>
64 #endif
65
66 #include <net/if_tun.h>
67
68 #define TUNDEBUG if (tundebug) printf
69 int tundebug = 0;
70
71 extern int ifqmaxlen;
72 void tunattach __P((int));
73 LIST_HEAD(, tun_softc) tun_softc_list;
74 static struct simplelock tun_softc_lock;
75
76 int tun_ioctl __P((struct ifnet *, u_long, caddr_t));
77 int tun_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
78 struct rtentry *rt));
79 int tun_clone_create __P((struct if_clone *, int));
80 void tun_clone_destroy __P((struct ifnet *));
81
82 struct if_clone tun_cloner =
83 IF_CLONE_INITIALIZER("tun", tun_clone_create, tun_clone_destroy);
84
85 static void tunattach0 __P((struct tun_softc *));
86 static void tuninit __P((struct tun_softc *));
87 static struct tun_softc *tun_find_unit __P((dev_t));
88
89 void
90 tunattach(unused)
91 int unused;
92 {
93
94 simple_lock_init(&tun_softc_lock);
95 LIST_INIT(&tun_softc_list);
96 if_clone_attach(&tun_cloner);
97 }
98
99 int
100 tun_clone_create(ifc, unit)
101 struct if_clone *ifc;
102 int unit;
103 {
104 struct tun_softc *sc;
105
106 sc = malloc(sizeof(struct tun_softc), M_DEVBUF, M_WAITOK);
107 (void)memset(sc, 0, sizeof(struct tun_softc));
108
109 (void)snprintf(sc->tun_if.if_xname, sizeof(sc->tun_if.if_xname),
110 "%s%d", ifc->ifc_name, unit);
111 sc->tun_unit = unit;
112 simple_lock_init(&sc->tun_lock);
113
114 tunattach0(sc);
115
116 simple_lock(&tun_softc_lock);
117 LIST_INSERT_HEAD(&tun_softc_list, sc, tun_list);
118 simple_unlock(&tun_softc_lock);
119
120 return (0);
121 }
122
123 void
124 tunattach0(sc)
125 struct tun_softc *sc;
126 {
127 struct ifnet *ifp = (void *)sc;
128
129 sc->tun_flags = TUN_INITED;
130
131 ifp = &sc->tun_if;
132 ifp->if_softc = sc;
133 ifp->if_mtu = TUNMTU;
134 ifp->if_ioctl = tun_ioctl;
135 ifp->if_output = tun_output;
136 ifp->if_flags = IFF_POINTOPOINT;
137 ifp->if_snd.ifq_maxlen = ifqmaxlen;
138 ifp->if_collisions = 0;
139 ifp->if_ierrors = 0;
140 ifp->if_oerrors = 0;
141 ifp->if_ipackets = 0;
142 ifp->if_opackets = 0;
143 ifp->if_dlt = DLT_NULL;
144 if_attach(ifp);
145 if_alloc_sadl(ifp);
146 #if NBPFILTER > 0
147 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
148 #endif
149 }
150
151 void
152 tun_clone_destroy(ifp)
153 struct ifnet *ifp;
154 {
155 struct tun_softc *tp = (void *)ifp;
156 struct proc *p;
157
158 simple_lock(&tun_softc_lock);
159 simple_lock(&tp->tun_lock);
160 LIST_REMOVE(tp, tun_list);
161 simple_unlock(&tp->tun_lock);
162 simple_unlock(&tun_softc_lock);
163
164 if (tp->tun_flags & TUN_RWAIT) {
165 tp->tun_flags &= ~TUN_RWAIT;
166 wakeup((caddr_t)tp);
167 }
168 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
169 if (tp->tun_pgrp > 0)
170 gsignal(tp->tun_pgrp, SIGIO);
171 else if ((p = pfind(-tp->tun_pgrp)) != NULL)
172 psignal(p, SIGIO);
173 }
174 selwakeup(&tp->tun_rsel);
175
176 #if NBPFILTER > 0
177 bpfdetach(ifp);
178 #endif
179 if_detach(ifp);
180
181 free(tp, M_DEVBUF);
182 }
183
184 static struct tun_softc *
185 tun_find_unit(dev)
186 dev_t dev;
187 {
188 struct tun_softc *tp;
189 int unit = minor(dev);
190
191 simple_lock(&tun_softc_lock);
192 LIST_FOREACH(tp, &tun_softc_list, tun_list)
193 if (unit == tp->tun_unit)
194 break;
195 if (tp)
196 simple_lock(&tp->tun_lock);
197 simple_unlock(&tun_softc_lock);
198
199 return (tp);
200 }
201
202 /*
203 * tunnel open - must be superuser & the device must be
204 * configured in
205 */
206 int
207 tunopen(dev, flag, mode, p)
208 dev_t dev;
209 int flag, mode;
210 struct proc *p;
211 {
212 struct ifnet *ifp;
213 struct tun_softc *tp;
214 int error;
215
216 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
217 return (error);
218
219 if (NTUN < 1)
220 return (ENXIO);
221
222 tp = tun_find_unit(dev);
223
224 if (!tp)
225 return (ENXIO);
226
227 if (tp->tun_flags & TUN_OPEN) {
228 simple_unlock(&tp->tun_lock);
229 return (EBUSY);
230 }
231
232 ifp = &tp->tun_if;
233 tp->tun_flags |= TUN_OPEN;
234 TUNDEBUG("%s: open\n", ifp->if_xname);
235 simple_unlock(&tp->tun_lock);
236 return (0);
237 }
238
239 /*
240 * tunclose - close the device - mark i/f down & delete
241 * routing info
242 */
243 int
244 tunclose(dev, flag, mode, p)
245 dev_t dev;
246 int flag;
247 int mode;
248 struct proc *p;
249 {
250 int s;
251 struct tun_softc *tp;
252 struct ifnet *ifp;
253 struct mbuf *m;
254
255 tp = tun_find_unit(dev);
256
257 /* interface was "destroyed" before the close */
258 if (tp == NULL)
259 return (0);
260
261 ifp = &tp->tun_if;
262
263 tp->tun_flags &= ~TUN_OPEN;
264
265 /*
266 * junk all pending output
267 */
268 do {
269 s = splnet();
270 IF_DEQUEUE(&ifp->if_snd, m);
271 splx(s);
272 if (m)
273 m_freem(m);
274 } while (m);
275
276 if (ifp->if_flags & IFF_UP) {
277 s = splnet();
278 if_down(ifp);
279 if (ifp->if_flags & IFF_RUNNING) {
280 /* find internet addresses and delete routes */
281 struct ifaddr *ifa;
282 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
283 #ifdef INET
284 if (ifa->ifa_addr->sa_family == AF_INET) {
285 rtinit(ifa, (int)RTM_DELETE,
286 tp->tun_flags & TUN_DSTADDR
287 ? RTF_HOST
288 : 0);
289 }
290 #endif
291 }
292 }
293 splx(s);
294 }
295 tp->tun_pgrp = 0;
296 selwakeup(&tp->tun_rsel);
297
298 TUNDEBUG ("%s: closed\n", ifp->if_xname);
299 simple_unlock(&tp->tun_lock);
300 return (0);
301 }
302
303 static void
304 tuninit(tp)
305 struct tun_softc *tp;
306 {
307 struct ifnet *ifp = &tp->tun_if;
308 struct ifaddr *ifa;
309
310 TUNDEBUG("%s: tuninit\n", ifp->if_xname);
311
312 ifp->if_flags |= IFF_UP | IFF_RUNNING;
313
314 tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
315 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
316 #ifdef INET
317 if (ifa->ifa_addr->sa_family == AF_INET) {
318 struct sockaddr_in *sin;
319
320 sin = satosin(ifa->ifa_addr);
321 if (sin && sin->sin_addr.s_addr)
322 tp->tun_flags |= TUN_IASET;
323
324 if (ifp->if_flags & IFF_POINTOPOINT) {
325 sin = satosin(ifa->ifa_dstaddr);
326 if (sin && sin->sin_addr.s_addr)
327 tp->tun_flags |= TUN_DSTADDR;
328 }
329 }
330 #endif
331 }
332
333 return;
334 }
335
336 /*
337 * Process an ioctl request.
338 */
339 int
340 tun_ioctl(ifp, cmd, data)
341 struct ifnet *ifp;
342 u_long cmd;
343 caddr_t data;
344 {
345 int error = 0, s;
346 struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
347
348 simple_lock(&tp->tun_lock);
349
350 s = splnet();
351 switch(cmd) {
352 case SIOCSIFADDR:
353 tuninit((struct tun_softc *)(ifp->if_softc));
354 TUNDEBUG("%s: address set\n", ifp->if_xname);
355 break;
356 case SIOCSIFDSTADDR:
357 tuninit((struct tun_softc *)(ifp->if_softc));
358 TUNDEBUG("%s: destination address set\n", ifp->if_xname);
359 break;
360 case SIOCSIFBRDADDR:
361 TUNDEBUG("%s: broadcast address set\n", ifp->if_xname);
362 break;
363 case SIOCSIFMTU: {
364 struct ifreq *ifr = (struct ifreq *) data;
365 if (ifr->ifr_mtu > TUNMTU || ifr->ifr_mtu < 576) {
366 error = EINVAL;
367 break;
368 }
369 TUNDEBUG("%s: interface mtu set\n", ifp->if_xname);
370 ifp->if_mtu = ifr->ifr_mtu;
371 break;
372 }
373 case SIOCADDMULTI:
374 case SIOCDELMULTI: {
375 struct ifreq *ifr = (struct ifreq *) data;
376 if (ifr == 0) {
377 error = EAFNOSUPPORT; /* XXX */
378 break;
379 }
380 switch (ifr->ifr_addr.sa_family) {
381
382 #ifdef INET
383 case AF_INET:
384 break;
385 #endif
386
387 default:
388 error = EAFNOSUPPORT;
389 break;
390 }
391 break;
392 }
393 case SIOCSIFFLAGS:
394 break;
395 default:
396 error = EINVAL;
397 }
398 splx(s);
399 simple_unlock(&tp->tun_lock);
400 return (error);
401 }
402
403 /*
404 * tun_output - queue packets from higher level ready to put out.
405 */
406 int
407 tun_output(ifp, m0, dst, rt)
408 struct ifnet *ifp;
409 struct mbuf *m0;
410 struct sockaddr *dst;
411 struct rtentry *rt;
412 {
413 struct tun_softc *tp = ifp->if_softc;
414 struct proc *p;
415 #ifdef INET
416 int s;
417 #endif
418
419 simple_lock(&tp->tun_lock);
420 TUNDEBUG ("%s: tun_output\n", ifp->if_xname);
421
422 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
423 TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname,
424 tp->tun_flags);
425 m_freem (m0);
426 simple_unlock(&tp->tun_lock);
427 return (EHOSTDOWN);
428 }
429
430 #if NBPFILTER > 0
431 if (ifp->if_bpf) {
432 /*
433 * We need to prepend the address family as
434 * a four byte field. Cons up a dummy header
435 * to pacify bpf. This is safe because bpf
436 * will only read from the mbuf (i.e., it won't
437 * try to free it or keep a pointer to it).
438 */
439 struct mbuf m;
440 u_int32_t af = dst->sa_family;
441
442 m.m_next = m0;
443 m.m_len = sizeof(af);
444 m.m_data = (char *)⁡
445
446 bpf_mtap(ifp->if_bpf, &m);
447 }
448 #endif
449
450 switch(dst->sa_family) {
451 #ifdef INET
452 case AF_INET:
453 if (tp->tun_flags & TUN_PREPADDR) {
454 /* Simple link-layer header */
455 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
456 if (m0 == NULL) {
457 IF_DROP(&ifp->if_snd);
458 simple_unlock(&tp->tun_lock);
459 return (ENOBUFS);
460 }
461 bcopy(dst, mtod(m0, char *), dst->sa_len);
462 }
463 /* FALLTHROUGH */
464 case AF_UNSPEC:
465 s = splnet();
466 if (IF_QFULL(&ifp->if_snd)) {
467 IF_DROP(&ifp->if_snd);
468 m_freem(m0);
469 splx(s);
470 ifp->if_collisions++;
471 simple_unlock(&tp->tun_lock);
472 return (ENOBUFS);
473 }
474 IF_ENQUEUE(&ifp->if_snd, m0);
475 splx(s);
476 ifp->if_opackets++;
477 break;
478 #endif
479 default:
480 m_freem(m0);
481 simple_unlock(&tp->tun_lock);
482 return (EAFNOSUPPORT);
483 }
484
485 if (tp->tun_flags & TUN_RWAIT) {
486 tp->tun_flags &= ~TUN_RWAIT;
487 wakeup((caddr_t)tp);
488 }
489 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
490 if (tp->tun_pgrp > 0)
491 gsignal(tp->tun_pgrp, SIGIO);
492 else if ((p = pfind(-tp->tun_pgrp)) != NULL)
493 psignal(p, SIGIO);
494 }
495 selwakeup(&tp->tun_rsel);
496 simple_unlock(&tp->tun_lock);
497 return (0);
498 }
499
500 /*
501 * the cdevsw interface is now pretty minimal.
502 */
503 int
504 tunioctl(dev, cmd, data, flag, p)
505 dev_t dev;
506 u_long cmd;
507 caddr_t data;
508 int flag;
509 struct proc *p;
510 {
511 int s;
512 struct tun_softc *tp;
513
514 tp = tun_find_unit(dev);
515
516 /* interface was "destroyed" already */
517 if (tp == NULL)
518 return (ENXIO);
519
520 switch (cmd) {
521 case TUNSDEBUG:
522 tundebug = *(int *)data;
523 break;
524
525 case TUNGDEBUG:
526 *(int *)data = tundebug;
527 break;
528
529 case TUNSIFMODE:
530 switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
531 case IFF_POINTOPOINT:
532 case IFF_BROADCAST:
533 s = splnet();
534 if (tp->tun_if.if_flags & IFF_UP) {
535 splx(s);
536 simple_unlock(&tp->tun_lock);
537 return (EBUSY);
538 }
539 tp->tun_if.if_flags &=
540 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
541 tp->tun_if.if_flags |= *(int *)data;
542 splx(s);
543 break;
544 default:
545 simple_unlock(&tp->tun_lock);
546 return (EINVAL);
547 break;
548 }
549 break;
550
551 case TUNSLMODE:
552 if (*(int *)data)
553 tp->tun_flags |= TUN_PREPADDR;
554 else
555 tp->tun_flags &= ~TUN_PREPADDR;
556 break;
557
558 case FIONBIO:
559 if (*(int *)data)
560 tp->tun_flags |= TUN_NBIO;
561 else
562 tp->tun_flags &= ~TUN_NBIO;
563 break;
564
565 case FIOASYNC:
566 if (*(int *)data)
567 tp->tun_flags |= TUN_ASYNC;
568 else
569 tp->tun_flags &= ~TUN_ASYNC;
570 break;
571
572 case FIONREAD:
573 s = splnet();
574 if (tp->tun_if.if_snd.ifq_head)
575 *(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len;
576 else
577 *(int *)data = 0;
578 splx(s);
579 break;
580
581 case TIOCSPGRP:
582 tp->tun_pgrp = *(int *)data;
583 break;
584
585 case TIOCGPGRP:
586 *(int *)data = tp->tun_pgrp;
587 break;
588
589 default:
590 simple_unlock(&tp->tun_lock);
591 return (ENOTTY);
592 }
593 simple_unlock(&tp->tun_lock);
594 return (0);
595 }
596
597 /*
598 * The cdevsw read interface - reads a packet at a time, or at
599 * least as much of a packet as can be read.
600 */
601 int
602 tunread(dev, uio, ioflag)
603 dev_t dev;
604 struct uio *uio;
605 int ioflag;
606 {
607 struct tun_softc *tp;
608 struct ifnet *ifp;
609 struct mbuf *m, *m0;
610 int error=0, len, s, index;
611
612 tp = tun_find_unit(dev);
613
614 /* interface was "destroyed" already */
615 if (tp == NULL)
616 return (ENXIO);
617
618 index = tp->tun_if.if_index;
619 ifp = &tp->tun_if;
620
621 TUNDEBUG ("%s: read\n", ifp->if_xname);
622 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
623 TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname, tp->tun_flags);
624 simple_unlock(&tp->tun_lock);
625 return EHOSTDOWN;
626 }
627
628 tp->tun_flags &= ~TUN_RWAIT;
629
630 s = splnet();
631 do {
632 IF_DEQUEUE(&ifp->if_snd, m0);
633 if (m0 == 0) {
634 if (tp->tun_flags & TUN_NBIO) {
635 splx(s);
636 simple_unlock(&tp->tun_lock);
637 return (EWOULDBLOCK);
638 }
639 tp->tun_flags |= TUN_RWAIT;
640 simple_unlock(&tp->tun_lock);
641 if (tsleep((caddr_t)tp, PZERO|PCATCH, "tunread", 0)) {
642 splx(s);
643 return (EINTR);
644 } else {
645 /*
646 * Maybe the interface was destroyed while
647 * we were sleeping, so let's ensure that
648 * we're looking at the same (valid) tun
649 * interface before looping.
650 */
651 tp = tun_find_unit(dev);
652 if (tp == NULL ||
653 tp->tun_if.if_index != index) {
654 splx(s);
655 if (tp)
656 simple_unlock(&tp->tun_lock);
657 return (ENXIO);
658 }
659 }
660 }
661 } while (m0 == 0);
662 splx(s);
663
664 while (m0 && uio->uio_resid > 0 && error == 0) {
665 len = min(uio->uio_resid, m0->m_len);
666 if (len != 0)
667 error = uiomove(mtod(m0, caddr_t), len, uio);
668 MFREE(m0, m);
669 m0 = m;
670 }
671
672 if (m0) {
673 TUNDEBUG("Dropping mbuf\n");
674 m_freem(m0);
675 }
676 if (error)
677 ifp->if_ierrors++;
678 simple_unlock(&tp->tun_lock);
679 return (error);
680 }
681
682 /*
683 * the cdevsw write interface - an atomic write is a packet - or else!
684 */
685 int
686 tunwrite(dev, uio, ioflag)
687 dev_t dev;
688 struct uio *uio;
689 int ioflag;
690 {
691 struct tun_softc *tp;
692 struct ifnet *ifp;
693 struct mbuf *top, **mp, *m;
694 struct ifqueue *ifq;
695 struct sockaddr dst;
696 int isr, error=0, s, tlen, mlen;
697
698 tp = tun_find_unit(dev);
699
700 /* interface was "destroyed" already */
701 if (tp == NULL)
702 return (ENXIO);
703
704 ifp = &tp->tun_if;
705
706 TUNDEBUG("%s: tunwrite\n", ifp->if_xname);
707
708 if (tp->tun_flags & TUN_PREPADDR) {
709 if (uio->uio_resid < sizeof(dst)) {
710 simple_unlock(&tp->tun_lock);
711 return (EIO);
712 }
713 error = uiomove((caddr_t)&dst, sizeof(dst), uio);
714 if (dst.sa_len > sizeof(dst)) {
715 /* Duh.. */
716 char discard;
717 int n = dst.sa_len - sizeof(dst);
718 while (n--)
719 if ((error = uiomove(&discard, 1, uio)) != 0) {
720 simple_unlock(&tp->tun_lock);
721 return (error);
722 }
723 }
724 } else {
725 #ifdef INET
726 dst.sa_family = AF_INET;
727 #endif
728 }
729
730 if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) {
731 TUNDEBUG("%s: len=%lu!\n", ifp->if_xname,
732 (unsigned long)uio->uio_resid);
733 simple_unlock(&tp->tun_lock);
734 return (EIO);
735 }
736
737 switch (dst.sa_family) {
738 #ifdef INET
739 case AF_INET:
740 ifq = &ipintrq;
741 isr = NETISR_IP;
742 break;
743 #endif
744 default:
745 simple_unlock(&tp->tun_lock);
746 return (EAFNOSUPPORT);
747 }
748
749 tlen = uio->uio_resid;
750
751 /* get a header mbuf */
752 MGETHDR(m, M_DONTWAIT, MT_DATA);
753 if (m == NULL) {
754 simple_unlock(&tp->tun_lock);
755 return (ENOBUFS);
756 }
757 mlen = MHLEN;
758
759 top = 0;
760 mp = ⊤
761 while (error == 0 && uio->uio_resid > 0) {
762 m->m_len = min(mlen, uio->uio_resid);
763 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
764 *mp = m;
765 mp = &m->m_next;
766 if (uio->uio_resid > 0) {
767 MGET (m, M_DONTWAIT, MT_DATA);
768 if (m == 0) {
769 error = ENOBUFS;
770 break;
771 }
772 mlen = MLEN;
773 }
774 }
775 if (error) {
776 if (top)
777 m_freem (top);
778 ifp->if_ierrors++;
779 simple_unlock(&tp->tun_lock);
780 return (error);
781 }
782
783 top->m_pkthdr.len = tlen;
784 top->m_pkthdr.rcvif = ifp;
785
786 #if NBPFILTER > 0
787 if (ifp->if_bpf) {
788 /*
789 * We need to prepend the address family as
790 * a four byte field. Cons up a dummy header
791 * to pacify bpf. This is safe because bpf
792 * will only read from the mbuf (i.e., it won't
793 * try to free it or keep a pointer to it).
794 */
795 struct mbuf m;
796 u_int32_t af = AF_INET;
797
798 m.m_next = top;
799 m.m_len = sizeof(af);
800 m.m_data = (char *)⁡
801
802 bpf_mtap(ifp->if_bpf, &m);
803 }
804 #endif
805
806 s = splnet();
807 if (IF_QFULL(ifq)) {
808 IF_DROP(ifq);
809 splx(s);
810 ifp->if_collisions++;
811 m_freem(top);
812 simple_unlock(&tp->tun_lock);
813 return (ENOBUFS);
814 }
815 IF_ENQUEUE(ifq, top);
816 splx(s);
817 ifp->if_ipackets++;
818 schednetisr(isr);
819 simple_unlock(&tp->tun_lock);
820 return (error);
821 }
822
823 /*
824 * tunpoll - the poll interface, this is only useful on reads
825 * really. The write detect always returns true, write never blocks
826 * anyway, it either accepts the packet or drops it.
827 */
828 int
829 tunpoll(dev, events, p)
830 dev_t dev;
831 int events;
832 struct proc *p;
833 {
834 struct tun_softc *tp;
835 struct ifnet *ifp;
836 int s, revents = 0;
837
838 tp = tun_find_unit(dev);
839
840 /* interface was "destroyed" already */
841 if (tp == NULL)
842 return (0);
843
844 ifp = &tp->tun_if;
845
846 s = splnet();
847 TUNDEBUG("%s: tunpoll\n", ifp->if_xname);
848
849 if (events & (POLLIN | POLLRDNORM)) {
850 if (ifp->if_snd.ifq_len > 0) {
851 TUNDEBUG("%s: tunpoll q=%d\n", ifp->if_xname,
852 ifp->if_snd.ifq_len);
853 revents |= events & (POLLIN | POLLRDNORM);
854 } else {
855 TUNDEBUG("%s: tunpoll waiting\n", ifp->if_xname);
856 selrecord(p, &tp->tun_rsel);
857 }
858 }
859
860 if (events & (POLLOUT | POLLWRNORM))
861 revents |= events & (POLLOUT | POLLWRNORM);
862
863 splx(s);
864 simple_unlock(&tp->tun_lock);
865 return (revents);
866 }
867
868 #endif /* NTUN */
869