[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
added kqueue support to tun(4)
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: added kqueue support to tun(4)
- From: Christopher Maxwell <cmaxwell_(_at_)_themanor_(_dot_)_net>
- Date: Mon, 24 Nov 2003 14:43:31 -0500 (EST)
Hello,
I added full kqueue support to the tun(4) driver, could some others please
test/comment/commit?
Specifically, the spl...() priorities were borrowed from the bpf(4)
driver, feedback on them would be appreciated.
cheers!
-=chris
--
Christopher Maxwell
cmaxwell_(_at_)_themanor_(_dot_)_net
--- if_tun.c.stable Fri Aug 15 16:32:19 2003
+++ if_tun.c Mon Nov 24 14:28:00 2003
@@ -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)
@@ -258,6 +262,7 @@
}
tp->tun_pgid = 0;
selwakeup(&tp->tun_rsel);
+ KNOTE(&tp->tun_rsel.si_note, 0);
TUNDEBUG(("%s: closed\n", ifp->if_xname));
return (0);
@@ -433,6 +438,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;
}
@@ -780,14 +786,124 @@
return 0;
}
-/* Does not currently work */
+/*
+ * kqueue(2) support.
+ *
+ * The tun driver uses an array of tun_softc's based on the minor number
+ * of the device. kn->kn_hook gets set to the specific tun_softc.
+ *
+ * filt_tunread() sets kn->kn_data to the iface qsize
+ * filt_tunwrite() sets kn->kn_data to the MTU size
+ */
+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)
{
- return (1);
+ int unit, s;
+ struct klist *klist;
+ struct tun_softc *tp;
+ struct ifnet *ifp;
+
+ if ((unit = minor(dev)) >= ntun)
+ return ENXIO;
+
+ tp = &tunctl[unit];
+ ifp = &tp->tun_if;
+
+ s = splimp();
+ TUNDEBUG(("%s: tunselect\n", ifp->if_xname));
+ splx(s);
+
+ 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 EPERM; /* 1 */
+ }
+
+ kn->kn_hook = (caddr_t)tp;
+
+ s = splhigh();
+ SLIST_INSERT_HEAD(klist, kn, kn_selnext);
+ splx(s);
+
+ return 0;
}
+void
+filt_tunrdetach(struct knote *kn)
+{
+ int s;
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+
+ s = splhigh();
+ SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+int
+filt_tunread(struct knote *kn, long hint)
+{
+ int s;
+ struct tun_softc *tp;
+ struct ifnet *ifp;
+ struct mbuf *m;
+
+ tp = (struct tun_softc *)kn->kn_hook;
+ ifp = &tp->tun_if;
+
+ s = splnet();
+ IFQ_POLL(&ifp->if_snd, m);
+ if (m != NULL) {
+ splx(s);
+ kn->kn_data = ifp->if_snd.ifq_len;
+
+ TUNDEBUG(("%s: tunkqread q=%d\n", ifp->if_xname,
+ ifp->if_snd.ifq_len));
+ return 1;
+ }
+ splx(s);
+ TUNDEBUG(("%s: tunkqread waiting\n", ifp->if_xname));
+ return 0;
+}
+
+void
+filt_tunwdetach(struct knote *kn)
+{
+ int s;
+ struct tun_softc *tp = (struct tun_softc *)kn->kn_hook;
+
+ s = splhigh();
+ SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext);
+ splx(s);
+}
+
+int
+filt_tunwrite(struct knote *kn, long hint)
+{
+ struct tun_softc *tp;
+ struct ifnet *ifp;
+
+ tp = (struct tun_softc *)kn->kn_hook;
+ ifp = &tp->tun_if;
+
+ kn->kn_data = ifp->if_mtu;
+
+ return 1;
+}
+
#ifdef ALTQ
/*
* Start packet transmission on the interface.
@@ -815,6 +931,7 @@
csignal(tp->tun_pgid, SIGIO,
tp->tun_siguid, tp->tun_sigeuid);
selwakeup(&tp->tun_rsel);
+ KNOTE(&tp->tun_rsel.si_note, 0);
}
}
#endif
Visit your host, monkey.org