1 /* $NetBSD: if_tun.c,v 1.110 2008/11/20 21:55:15 dyoung Exp $ */
4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5 * Nottingham University 1987.
7 * This source may be freely distributed, however I would be interested
8 * in any changes that are made.
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
17 #include <sys/cdefs.h>
18 __KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.110 2008/11/20 21:55:15 dyoung Exp $");
22 #include <sys/param.h>
24 #include <sys/systm.h>
27 #include <sys/protosw.h>
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
30 #include <sys/errno.h>
31 #include <sys/syslog.h>
32 #include <sys/select.h>
35 #include <sys/signalvar.h>
37 #include <sys/kauth.h>
38 #include <sys/simplelock.h>
42 #include <net/if_types.h>
43 #include <net/netisr.h>
44 #include <net/route.h>
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>
62 #include <net/if_tun.h>
64 #define TUNDEBUG if (tundebug) printf
70 static LIST_HEAD(, tun_softc
) tun_softc_list
;
71 static LIST_HEAD(, tun_softc
) tunz_softc_list
;
72 static struct simplelock tun_softc_lock
;
74 static int tun_ioctl(struct ifnet
*, u_long
, void *);
75 static int tun_output(struct ifnet
*, struct mbuf
*,
76 const struct sockaddr
*, struct rtentry
*rt
);
77 static int tun_clone_create(struct if_clone
*, int);
78 static int tun_clone_destroy(struct ifnet
*);
80 static struct if_clone tun_cloner
=
81 IF_CLONE_INITIALIZER("tun", tun_clone_create
, tun_clone_destroy
);
83 static void tunattach0(struct tun_softc
*);
84 static void tuninit(struct tun_softc
*);
85 static void tun_i_softintr(void *);
86 static void tun_o_softintr(void *);
88 static void tunstart(struct ifnet
*);
90 static struct tun_softc
*tun_find_unit(dev_t
);
91 static struct tun_softc
*tun_find_zunit(int);
93 static dev_type_open(tunopen
);
94 static dev_type_close(tunclose
);
95 static dev_type_read(tunread
);
96 static dev_type_write(tunwrite
);
97 static dev_type_ioctl(tunioctl
);
98 static dev_type_poll(tunpoll
);
99 static dev_type_kqfilter(tunkqfilter
);
101 const struct cdevsw tun_cdevsw
= {
102 tunopen
, tunclose
, tunread
, tunwrite
, tunioctl
,
103 nostop
, notty
, tunpoll
, nommap
, tunkqfilter
, D_OTHER
,
107 tunattach(int unused
)
110 simple_lock_init(&tun_softc_lock
);
111 LIST_INIT(&tun_softc_list
);
112 LIST_INIT(&tunz_softc_list
);
113 if_clone_attach(&tun_cloner
);
117 * Find driver instance from dev_t.
119 * Returns with tp locked (if found).
121 static struct tun_softc
*
122 tun_find_unit(dev_t dev
)
124 struct tun_softc
*tp
;
125 int unit
= minor(dev
);
127 simple_lock(&tun_softc_lock
);
128 LIST_FOREACH(tp
, &tun_softc_list
, tun_list
)
129 if (unit
== tp
->tun_unit
)
132 simple_lock(&tp
->tun_lock
);
133 simple_unlock(&tun_softc_lock
);
139 * Find zombie driver instance by unit number.
141 * Remove tp from list and return it unlocked (if found).
143 static struct tun_softc
*
144 tun_find_zunit(int unit
)
146 struct tun_softc
*tp
;
148 simple_lock(&tun_softc_lock
);
149 LIST_FOREACH(tp
, &tunz_softc_list
, tun_list
)
150 if (unit
== tp
->tun_unit
)
153 LIST_REMOVE(tp
, tun_list
);
154 simple_unlock(&tun_softc_lock
);
156 if (tp
!= NULL
&& (tp
->tun_flags
& (TUN_INITED
|TUN_OPEN
)) != TUN_OPEN
)
157 printf("tun%d: inconsistent flags: %x\n", unit
, tp
->tun_flags
);
164 tun_clone_create(struct if_clone
*ifc
, int unit
)
166 struct tun_softc
*tp
;
168 if ((tp
= tun_find_zunit(unit
)) == NULL
) {
169 /* Allocate a new instance */
170 tp
= malloc(sizeof(*tp
), M_DEVBUF
, M_WAITOK
|M_ZERO
);
173 simple_lock_init(&tp
->tun_lock
);
174 selinit(&tp
->tun_rsel
);
175 selinit(&tp
->tun_wsel
);
177 /* Revive tunnel instance; clear ifp part */
178 (void)memset(&tp
->tun_if
, 0, sizeof(struct ifnet
));
181 if_initname(&tp
->tun_if
, ifc
->ifc_name
, unit
);
183 tp
->tun_flags
|= TUN_INITED
;
184 tp
->tun_osih
= softint_establish(SOFTINT_CLOCK
, tun_o_softintr
, tp
);
185 tp
->tun_isih
= softint_establish(SOFTINT_CLOCK
, tun_i_softintr
, tp
);
187 simple_lock(&tun_softc_lock
);
188 LIST_INSERT_HEAD(&tun_softc_list
, tp
, tun_list
);
189 simple_unlock(&tun_softc_lock
);
195 tunattach0(struct tun_softc
*tp
)
201 ifp
->if_mtu
= TUNMTU
;
202 ifp
->if_ioctl
= tun_ioctl
;
203 ifp
->if_output
= tun_output
;
205 ifp
->if_start
= tunstart
;
207 ifp
->if_flags
= IFF_POINTOPOINT
;
208 ifp
->if_type
= IFT_TUNNEL
;
209 ifp
->if_snd
.ifq_maxlen
= ifqmaxlen
;
210 ifp
->if_collisions
= 0;
213 ifp
->if_ipackets
= 0;
214 ifp
->if_opackets
= 0;
217 ifp
->if_dlt
= DLT_NULL
;
218 IFQ_SET_READY(&ifp
->if_snd
);
222 bpfattach(ifp
, DLT_NULL
, sizeof(uint32_t));
227 tun_clone_destroy(struct ifnet
*ifp
)
229 struct tun_softc
*tp
= (void *)ifp
;
233 simple_lock(&tun_softc_lock
);
234 simple_lock(&tp
->tun_lock
);
235 LIST_REMOVE(tp
, tun_list
);
236 if (tp
->tun_flags
& TUN_OPEN
) {
237 /* Hang on to storage until last close */
239 tp
->tun_flags
&= ~TUN_INITED
;
240 LIST_INSERT_HEAD(&tunz_softc_list
, tp
, tun_list
);
242 simple_unlock(&tun_softc_lock
);
244 IF_PURGE(&ifp
->if_snd
);
245 ifp
->if_flags
&= ~IFF_RUNNING
;
247 if (tp
->tun_flags
& TUN_RWAIT
) {
248 tp
->tun_flags
&= ~TUN_RWAIT
;
251 selnotify(&tp
->tun_rsel
, 0, 0);
253 simple_unlock(&tp
->tun_lock
);
256 if (tp
->tun_flags
& TUN_ASYNC
&& tp
->tun_pgid
)
257 fownsignal(tp
->tun_pgid
, SIGIO
, POLL_HUP
, 0, NULL
);
265 seldestroy(&tp
->tun_rsel
);
266 seldestroy(&tp
->tun_wsel
);
267 softint_disestablish(tp
->tun_osih
);
268 softint_disestablish(tp
->tun_isih
);
276 * tunnel open - must be superuser & the device must be
280 tunopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
283 struct tun_softc
*tp
;
286 error
= kauth_authorize_network(l
->l_cred
, KAUTH_NETWORK_INTERFACE_TUN
,
287 KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD
, NULL
, NULL
, NULL
);
292 tp
= tun_find_unit(dev
);
295 (void)tun_clone_create(&tun_cloner
, minor(dev
));
296 tp
= tun_find_unit(dev
);
303 if (tp
->tun_flags
& TUN_OPEN
) {
309 tp
->tun_flags
|= TUN_OPEN
;
310 TUNDEBUG("%s: open\n", ifp
->if_xname
);
312 simple_unlock(&tp
->tun_lock
);
319 * tunclose - close the device - mark i/f down & delete
323 tunclose(dev_t dev
, int flag
, int mode
,
327 struct tun_softc
*tp
;
331 if ((tp
= tun_find_zunit(minor(dev
))) != NULL
) {
332 /* interface was "destroyed" before the close */
333 seldestroy(&tp
->tun_rsel
);
334 seldestroy(&tp
->tun_wsel
);
335 softint_disestablish(tp
->tun_osih
);
336 softint_disestablish(tp
->tun_isih
);
341 if ((tp
= tun_find_unit(dev
)) == NULL
)
346 tp
->tun_flags
&= ~TUN_OPEN
;
349 * junk all pending output
351 IFQ_PURGE(&ifp
->if_snd
);
353 if (ifp
->if_flags
& IFF_UP
) {
355 if (ifp
->if_flags
& IFF_RUNNING
) {
356 /* find internet addresses and delete routes */
358 IFADDR_FOREACH(ifa
, ifp
) {
359 #if defined(INET) || defined(INET6)
360 if (ifa
->ifa_addr
->sa_family
== AF_INET
||
361 ifa
->ifa_addr
->sa_family
== AF_INET6
) {
362 rtinit(ifa
, (int)RTM_DELETE
,
363 tp
->tun_flags
& TUN_DSTADDR
372 selnotify(&tp
->tun_rsel
, 0, 0);
374 TUNDEBUG ("%s: closed\n", ifp
->if_xname
);
375 simple_unlock(&tp
->tun_lock
);
385 tuninit(struct tun_softc
*tp
)
387 struct ifnet
*ifp
= &tp
->tun_if
;
390 TUNDEBUG("%s: tuninit\n", ifp
->if_xname
);
392 simple_lock(&tp
->tun_lock
);
393 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
395 tp
->tun_flags
&= ~(TUN_IASET
|TUN_DSTADDR
);
396 IFADDR_FOREACH(ifa
, ifp
) {
398 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
399 struct sockaddr_in
*sin
;
401 sin
= satosin(ifa
->ifa_addr
);
402 if (sin
&& sin
->sin_addr
.s_addr
)
403 tp
->tun_flags
|= TUN_IASET
;
405 if (ifp
->if_flags
& IFF_POINTOPOINT
) {
406 sin
= satosin(ifa
->ifa_dstaddr
);
407 if (sin
&& sin
->sin_addr
.s_addr
)
408 tp
->tun_flags
|= TUN_DSTADDR
;
413 if (ifa
->ifa_addr
->sa_family
== AF_INET6
) {
414 struct sockaddr_in6
*sin
;
416 sin
= (struct sockaddr_in6
*)ifa
->ifa_addr
;
417 if (!IN6_IS_ADDR_UNSPECIFIED(&sin
->sin6_addr
))
418 tp
->tun_flags
|= TUN_IASET
;
420 if (ifp
->if_flags
& IFF_POINTOPOINT
) {
421 sin
= (struct sockaddr_in6
*)ifa
->ifa_dstaddr
;
423 !IN6_IS_ADDR_UNSPECIFIED(&sin
->sin6_addr
))
424 tp
->tun_flags
|= TUN_DSTADDR
;
426 tp
->tun_flags
&= ~TUN_DSTADDR
;
431 simple_unlock(&tp
->tun_lock
);
436 * Process an ioctl request.
439 tun_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
442 struct tun_softc
*tp
= (struct tun_softc
*)(ifp
->if_softc
);
443 struct ifreq
*ifr
= data
;
450 TUNDEBUG("%s: address set\n", ifp
->if_xname
);
454 TUNDEBUG("%s: destination address set\n", ifp
->if_xname
);
457 TUNDEBUG("%s: broadcast address set\n", ifp
->if_xname
);
460 if (ifr
->ifr_mtu
> TUNMTU
|| ifr
->ifr_mtu
< 576) {
464 TUNDEBUG("%s: interface mtu set\n", ifp
->if_xname
);
465 if ((error
= ifioctl_common(ifp
, cmd
, data
)) == ENETRESET
)
471 error
= EAFNOSUPPORT
; /* XXX */
474 switch (ifreq_getaddr(cmd
, ifr
)->sa_family
) {
484 error
= EAFNOSUPPORT
;
489 error
= ifioctl_common(ifp
, cmd
, data
);
497 * tun_output - queue packets from higher level ready to put out.
500 tun_output(struct ifnet
*ifp
, struct mbuf
*m0
, const struct sockaddr
*dst
,
503 struct tun_softc
*tp
= ifp
->if_softc
;
506 #if defined(INET) || defined(INET6)
510 ALTQ_DECL(struct altq_pktattr pktattr
;)
513 simple_lock(&tp
->tun_lock
);
514 TUNDEBUG ("%s: tun_output\n", ifp
->if_xname
);
516 if ((tp
->tun_flags
& TUN_READY
) != TUN_READY
) {
517 TUNDEBUG ("%s: not ready 0%o\n", ifp
->if_xname
,
525 * if the queueing discipline needs packet classification,
526 * do it before prepending link headers.
528 IFQ_CLASSIFY(&ifp
->if_snd
, m0
, dst
->sa_family
, &pktattr
);
532 bpf_mtap_af(ifp
->if_bpf
, dst
->sa_family
, m0
);
535 switch(dst
->sa_family
) {
542 #if defined(INET) || defined(INET6)
543 if (tp
->tun_flags
& TUN_PREPADDR
) {
544 /* Simple link-layer header */
545 M_PREPEND(m0
, dst
->sa_len
, M_DONTWAIT
);
547 IF_DROP(&ifp
->if_snd
);
551 bcopy(dst
, mtod(m0
, char *), dst
->sa_len
);
554 if (tp
->tun_flags
& TUN_IFHEAD
) {
555 /* Prepend the address family */
556 M_PREPEND(m0
, sizeof(*af
), M_DONTWAIT
);
558 IF_DROP(&ifp
->if_snd
);
562 af
= mtod(m0
,uint32_t *);
563 *af
= htonl(dst
->sa_family
);
566 if (dst
->sa_family
!= AF_INET
)
570 error
= EAFNOSUPPORT
;
576 IFQ_ENQUEUE(&ifp
->if_snd
, m0
, &pktattr
, error
);
578 ifp
->if_collisions
++;
579 error
= EAFNOSUPPORT
;
582 mlen
= m0
->m_pkthdr
.len
;
584 ifp
->if_obytes
+= mlen
;
589 error
= EAFNOSUPPORT
;
593 if (tp
->tun_flags
& TUN_RWAIT
) {
594 tp
->tun_flags
&= ~TUN_RWAIT
;
597 if (tp
->tun_flags
& TUN_ASYNC
&& tp
->tun_pgid
)
598 softint_schedule(tp
->tun_isih
);
600 selnotify(&tp
->tun_rsel
, 0, 0);
602 simple_unlock(&tp
->tun_lock
);
608 tun_i_softintr(void *cookie
)
610 struct tun_softc
*tp
= cookie
;
612 if (tp
->tun_flags
& TUN_ASYNC
&& tp
->tun_pgid
)
613 fownsignal(tp
->tun_pgid
, SIGIO
, POLL_IN
, POLLIN
|POLLRDNORM
,
618 tun_o_softintr(void *cookie
)
620 struct tun_softc
*tp
= cookie
;
622 if (tp
->tun_flags
& TUN_ASYNC
&& tp
->tun_pgid
)
623 fownsignal(tp
->tun_pgid
, SIGIO
, POLL_OUT
, POLLOUT
|POLLWRNORM
,
628 * the cdevsw interface is now pretty minimal.
631 tunioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
633 struct tun_softc
*tp
;
637 tp
= tun_find_unit(dev
);
639 /* interface was "destroyed" already */
647 tundebug
= *(int *)data
;
651 *(int *)data
= tundebug
;
655 switch (*(int *)data
& (IFF_POINTOPOINT
|IFF_BROADCAST
)) {
656 case IFF_POINTOPOINT
:
658 if (tp
->tun_if
.if_flags
& IFF_UP
) {
662 tp
->tun_if
.if_flags
&=
663 ~(IFF_BROADCAST
|IFF_POINTOPOINT
|IFF_MULTICAST
);
664 tp
->tun_if
.if_flags
|= *(int *)data
;
674 tp
->tun_flags
|= TUN_PREPADDR
;
675 tp
->tun_flags
&= ~TUN_IFHEAD
;
677 tp
->tun_flags
&= ~TUN_PREPADDR
;
682 tp
->tun_flags
|= TUN_IFHEAD
;
683 tp
->tun_flags
&= ~TUN_PREPADDR
;
685 tp
->tun_flags
&= ~TUN_IFHEAD
;
689 *(int *)data
= (tp
->tun_flags
& TUN_IFHEAD
);
694 tp
->tun_flags
|= TUN_NBIO
;
696 tp
->tun_flags
&= ~TUN_NBIO
;
701 tp
->tun_flags
|= TUN_ASYNC
;
703 tp
->tun_flags
&= ~TUN_ASYNC
;
707 if (tp
->tun_if
.if_snd
.ifq_head
)
708 *(int *)data
= tp
->tun_if
.if_snd
.ifq_head
->m_pkthdr
.len
;
715 error
= fsetown(&tp
->tun_pgid
, cmd
, data
);
720 error
= fgetown(tp
->tun_pgid
, cmd
, data
);
728 simple_unlock(&tp
->tun_lock
);
735 * The cdevsw read interface - reads a packet at a time, or at
736 * least as much of a packet as can be read.
739 tunread(dev_t dev
, struct uio
*uio
, int ioflag
)
741 struct tun_softc
*tp
;
744 int error
= 0, len
, s
, index
;
747 tp
= tun_find_unit(dev
);
749 /* interface was "destroyed" already */
755 index
= tp
->tun_if
.if_index
;
758 TUNDEBUG ("%s: read\n", ifp
->if_xname
);
759 if ((tp
->tun_flags
& TUN_READY
) != TUN_READY
) {
760 TUNDEBUG ("%s: not ready 0%o\n", ifp
->if_xname
, tp
->tun_flags
);
765 tp
->tun_flags
&= ~TUN_RWAIT
;
768 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
770 if (tp
->tun_flags
& TUN_NBIO
) {
774 tp
->tun_flags
|= TUN_RWAIT
;
775 if (ltsleep((void *)tp
, PZERO
|PCATCH
|PNORELOCK
,
776 "tunread", 0, &tp
->tun_lock
) != 0) {
781 * Maybe the interface was destroyed while
782 * we were sleeping, so let's ensure that
783 * we're looking at the same (valid) tun
784 * interface before looping.
786 tp
= tun_find_unit(dev
);
791 if (tp
->tun_if
.if_index
!= index
) {
799 simple_unlock(&tp
->tun_lock
);
802 /* Copy the mbuf chain */
803 while (m0
&& uio
->uio_resid
> 0 && error
== 0) {
804 len
= min(uio
->uio_resid
, m0
->m_len
);
806 error
= uiomove(mtod(m0
, void *), len
, uio
);
812 TUNDEBUG("Dropping mbuf\n");
821 simple_unlock(&tp
->tun_lock
);
828 * the cdevsw write interface - an atomic write is a packet - or else!
831 tunwrite(dev_t dev
, struct uio
*uio
, int ioflag
)
833 struct tun_softc
*tp
;
835 struct mbuf
*top
, **mp
, *m
;
838 int isr
, error
= 0, s
, tlen
, mlen
;
842 tp
= tun_find_unit(dev
);
844 /* interface was "destroyed" already */
850 /* Unlock until we've got the data */
851 simple_unlock(&tp
->tun_lock
);
856 TUNDEBUG("%s: tunwrite\n", ifp
->if_xname
);
858 if (tp
->tun_flags
& TUN_PREPADDR
) {
859 if (uio
->uio_resid
< sizeof(dst
)) {
863 error
= uiomove((void *)&dst
, sizeof(dst
), uio
);
864 if (dst
.sa_len
> sizeof(dst
)) {
867 int n
= dst
.sa_len
- sizeof(dst
);
869 if ((error
= uiomove(&discard
, 1, uio
)) != 0) {
873 } else if (tp
->tun_flags
& TUN_IFHEAD
) {
874 if (uio
->uio_resid
< sizeof(family
)){
878 error
= uiomove((void *)&family
, sizeof(family
), uio
);
879 dst
.sa_family
= ntohl(family
);
882 dst
.sa_family
= AF_INET
;
886 if (uio
->uio_resid
> TUNMTU
) {
887 TUNDEBUG("%s: len=%lu!\n", ifp
->if_xname
,
888 (unsigned long)uio
->uio_resid
);
893 switch (dst
.sa_family
) {
907 error
= EAFNOSUPPORT
;
911 tlen
= uio
->uio_resid
;
913 /* get a header mbuf */
914 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
923 while (error
== 0 && uio
->uio_resid
> 0) {
924 m
->m_len
= min(mlen
, uio
->uio_resid
);
925 error
= uiomove(mtod(m
, void *), m
->m_len
, uio
);
928 if (error
== 0 && uio
->uio_resid
> 0) {
929 MGET(m
, M_DONTWAIT
, MT_DATA
);
944 top
->m_pkthdr
.len
= tlen
;
945 top
->m_pkthdr
.rcvif
= ifp
;
949 bpf_mtap_af(ifp
->if_bpf
, dst
.sa_family
, top
);
953 simple_lock(&tp
->tun_lock
);
954 if ((tp
->tun_flags
& TUN_INITED
) == 0) {
955 /* Interface was destroyed */
961 ifp
->if_collisions
++;
967 IF_ENQUEUE(ifq
, top
);
969 ifp
->if_ibytes
+= tlen
;
972 simple_unlock(&tp
->tun_lock
);
981 * Start packet transmission on the interface.
982 * when the interface queue is rate-limited by ALTQ or TBR,
983 * if_start is needed to drain packets from the queue in order
984 * to notify readers when outgoing packets become ready.
986 * Should be called at splnet.
989 tunstart(struct ifnet
*ifp
)
991 struct tun_softc
*tp
= ifp
->if_softc
;
993 if (!ALTQ_IS_ENABLED(&ifp
->if_snd
) && !TBR_IS_ENABLED(&ifp
->if_snd
))
996 simple_lock(&tp
->tun_lock
);
997 if (!IF_IS_EMPTY(&ifp
->if_snd
)) {
998 if (tp
->tun_flags
& TUN_RWAIT
) {
999 tp
->tun_flags
&= ~TUN_RWAIT
;
1002 if (tp
->tun_flags
& TUN_ASYNC
&& tp
->tun_pgid
)
1003 softint_schedule(tp
->tun_osih
);
1005 selnotify(&tp
->tun_rsel
, 0, 0);
1007 simple_unlock(&tp
->tun_lock
);
1011 * tunpoll - the poll interface, this is only useful on reads
1012 * really. The write detect always returns true, write never blocks
1013 * anyway, it either accepts the packet or drops it.
1016 tunpoll(dev_t dev
, int events
, struct lwp
*l
)
1018 struct tun_softc
*tp
;
1023 tp
= tun_find_unit(dev
);
1025 /* interface was "destroyed" already */
1031 TUNDEBUG("%s: tunpoll\n", ifp
->if_xname
);
1033 if (events
& (POLLIN
| POLLRDNORM
)) {
1034 if (!IFQ_IS_EMPTY(&ifp
->if_snd
)) {
1035 TUNDEBUG("%s: tunpoll q=%d\n", ifp
->if_xname
,
1036 ifp
->if_snd
.ifq_len
);
1037 revents
|= events
& (POLLIN
| POLLRDNORM
);
1039 TUNDEBUG("%s: tunpoll waiting\n", ifp
->if_xname
);
1040 selrecord(l
, &tp
->tun_rsel
);
1044 if (events
& (POLLOUT
| POLLWRNORM
))
1045 revents
|= events
& (POLLOUT
| POLLWRNORM
);
1047 simple_unlock(&tp
->tun_lock
);
1054 filt_tunrdetach(struct knote
*kn
)
1056 struct tun_softc
*tp
= kn
->kn_hook
;
1060 SLIST_REMOVE(&tp
->tun_rsel
.sel_klist
, kn
, knote
, kn_selnext
);
1065 filt_tunread(struct knote
*kn
, long hint
)
1067 struct tun_softc
*tp
= kn
->kn_hook
;
1068 struct ifnet
*ifp
= &tp
->tun_if
;
1073 IF_POLL(&ifp
->if_snd
, m
);
1079 for (kn
->kn_data
= 0; m
!= NULL
; m
= m
->m_next
)
1080 kn
->kn_data
+= m
->m_len
;
1086 static const struct filterops tunread_filtops
=
1087 { 1, NULL
, filt_tunrdetach
, filt_tunread
};
1089 static const struct filterops tun_seltrue_filtops
=
1090 { 1, NULL
, filt_tunrdetach
, filt_seltrue
};
1093 tunkqfilter(dev_t dev
, struct knote
*kn
)
1095 struct tun_softc
*tp
;
1096 struct klist
*klist
;
1100 tp
= tun_find_unit(dev
);
1104 switch (kn
->kn_filter
) {
1106 klist
= &tp
->tun_rsel
.sel_klist
;
1107 kn
->kn_fop
= &tunread_filtops
;
1111 klist
= &tp
->tun_rsel
.sel_klist
;
1112 kn
->kn_fop
= &tun_seltrue_filtops
;
1122 SLIST_INSERT_HEAD(klist
, kn
, kn_selnext
);
1125 simple_unlock(&tp
->tun_lock
);