kernel/3174: Add kqueue(2) support to tun(4)
>Number: 3174
>Category: kernel
>Synopsis: Add kqueue(2) support to tun(4)
>Confidential: yes
>Severity: non-critical
>Priority: low
>Responsible: bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Mar 30 03:40:01 GMT 2003
>Closed-Date:
>Last-Modified:
>Originator:
>Release: 3.3-current (cvs as at March 30)
>Organization:
net
>Environment:
System : OpenBSD 3.3
Architecture: OpenBSD.i386
Machine : i386
>Description:
The tun(4) interface currently lacks support for kqueue(2)/kevent(2).
This patch adds support. Partially from NetBSD.
>How-To-Repeat:
Try to register kevent(2) EVFILT_READ or EVFILT_WRITE events on tun(4)
>Fix:
Index: sys/net/if_tun.c
RCS file: /cvs/src/sys/net/if_tun.c,v
retrieving revision 1.45
diff -u -r1.45 if_tun.c
--- sys/net/if_tun.c 2003/01/07 09:00:34 1.45
+++ sys/net/if_tun.c 2003/03/30 03:14:20
@@ -136,6 +136,10 @@
#ifdef ALTQ
static void tunstart(struct ifnet *);
#endif
+int filt_tunread(struct knote *, long);
+int filt_tunwrite(struct knote *, long);
+void filt_tunrdetach(struct knote *);
+void filt_tunwdetach(struct knote *);
void
tunattach(n)
@@ -416,6 +420,7 @@
csignal(tp->tun_pgid, SIGIO,
tp->tun_siguid, tp->tun_sigeuid);
selwakeup(&tp->tun_rsel);
+ KNOTE(&tp->tun_rsel.si_note, 0);
return 0;
}
@@ -759,11 +764,96 @@
return 0;
}
-/* Does not currently work */
+struct filterops tunread_filtops =
+ { 1, NULL, filt_tunrdetach, filt_tunread };
+struct filterops tunwrite_filtops =
+ { 1, NULL, filt_tunwdetach, filt_tunwrite };
+
int
-tunkqfilter(dev_t dev,struct knote *kn)
+tunkqfilter(dev_t dev, struct knote *kn)
{
+ struct klist *klist;
+ struct tun_softc *tp;
+ int unit, s;
+
+ if ((unit = minor(dev)) >= ntun)
+ return (1);
+
+ tp = &tunctl[unit];
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ klist = &tp->tun_rsel.si_note;
+ kn->kn_fop = &tunread_filtops;
+ break;
+ case EVFILT_WRITE:
+ klist = &tp->tun_wsel.si_note;
+ kn->kn_fop = &tunwrite_filtops;
+ break;
+ default:
+ return (1);
+ }
+ kn->kn_hook = (caddr_t)tp;
+
+ s = splimp();
+ SLIST_INSERT_HEAD(klist, kn, kn_selnext);
+ splx(s);
+
+ return (0);
+}
+
+void
+filt_tunrdetach(struct knote *kn)
+{
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+ int s;
+
+ s = splimp();
+ SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+void
+filt_tunwdetach(struct knote *kn)
+{
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+ int s;
+
+ s = splimp();
+ SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+int
+filt_tunread(struct knote *kn, long hint)
+{
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+ struct ifnet *ifp = &tp->tun_if;
+ struct mbuf *m;
+ int s;
+
+ s = splnet();
+ IF_POLL(&ifp->if_snd, m);
+ if (m == NULL) {
+ splx(s);
+ return (0);
+ }
+
+ for (kn->kn_data = 0; m != NULL; m = m->m_next)
+ kn->kn_data += m->m_len;
+
+ splx(s);
+ return (1);
+}
+
+int
+filt_tunwrite(struct knote *kn, long hint)
+{
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+ struct ifnet *ifp = &tp->tun_if;
+
+ kn->kn_data = ifp->if_mtu;
return (1);
}
@@ -794,6 +884,7 @@
csignal(tp->tun_pgid, SIGIO,
tp->tun_siguid, tp->tun_sigeuid);
selwakeup(&tp->tun_rsel);
+ KNOTE(&tp->tun_rsel.si_note, 0);
}
}
#endif
>Release-Note:
>Audit-Trail:
>Unformatted:
Received on Sat Mar 29 22:46:33 2003
This archive was generated by hypermail 2.1.8
: Wed Aug 23 2006 - 13:29:52 EDT
|