[TEST] tun(4) and tap(4) improvement
Gleb Smirnoff
glebius at freebsd.org
Sun Oct 17 05:54:14 PDT 2004
Dear current users,
please test attached patches to tun(4) and tap(4), if
you utilize one of these drivers. I'm planning to add
them to tree.
tun(4) patch is already tested with a small test, but
I'd be glad if someone tests it under some load.
tap(4) isn't tested but the patch is very similar to tun's.
Thanks in advance.
--
Totus tuus, Glebius.
GLEBIUS-RIPN GLEB-RIPE
-------------- next part --------------
Index: if_tun.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_tun.c,v
retrieving revision 1.145
diff -u -r1.145 if_tun.c
--- if_tun.c 11 Oct 2004 07:28:36 -0000 1.145
+++ if_tun.c 17 Oct 2004 12:39:18 -0000
@@ -739,8 +739,8 @@
{
struct tun_softc *tp = dev->si_drv1;
struct ifnet *ifp = &tp->tun_if;
- struct mbuf *top, **mp, *m;
- int error=0, tlen, mlen;
+ struct mbuf *m;
+ int error = 0;
uint32_t family;
int isr;
@@ -757,58 +757,32 @@
TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid);
return (EIO);
}
- tlen = uio->uio_resid;
- /* get a header mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (ENOBUFS);
- mlen = MHLEN;
-
- top = NULL;
- mp = ⊤
- while (error == 0 && uio->uio_resid > 0) {
- m->m_len = min(mlen, uio->uio_resid);
- error = uiomove(mtod(m, void *), m->m_len, uio);
- *mp = m;
- mp = &m->m_next;
- if (uio->uio_resid > 0) {
- MGET (m, M_DONTWAIT, MT_DATA);
- if (m == 0) {
- error = ENOBUFS;
- break;
- }
- mlen = MLEN;
- }
- }
- if (error) {
- if (top)
- m_freem (top);
+ if ((m = m_uiotombuf(uio, M_DONTWAIT, 0)) == NULL) {
ifp->if_ierrors++;
return (error);
}
- top->m_pkthdr.len = tlen;
- top->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.rcvif = ifp;
#ifdef MAC
- mac_create_mbuf_from_ifnet(ifp, top);
+ mac_create_mbuf_from_ifnet(ifp, m);
#endif
/* Could be unlocked read? */
mtx_lock(&tp->tun_mtx);
if (tp->tun_flags & TUN_IFHEAD) {
mtx_unlock(&tp->tun_mtx);
- if (top->m_len < sizeof(family) &&
- (top = m_pullup(top, sizeof(family))) == NULL)
+ if (m->m_len < sizeof(family) &&
+ (m = m_pullup(m, sizeof(family))) == NULL)
return (ENOBUFS);
- family = ntohl(*mtod(top, u_int32_t *));
- m_adj(top, sizeof(family));
+ family = ntohl(*mtod(m, u_int32_t *));
+ m_adj(m, sizeof(family));
} else {
mtx_unlock(&tp->tun_mtx);
family = AF_INET;
}
- BPF_MTAP2(ifp, &family, sizeof(family), top);
+ BPF_MTAP2(ifp, &family, sizeof(family), m);
switch (family) {
#ifdef INET
@@ -838,9 +812,9 @@
/* First chunk of an mbuf contains good junk */
if (harvest.point_to_point)
random_harvest(m, 16, 3, 0, RANDOM_NET);
- ifp->if_ibytes += top->m_pkthdr.len;
+ ifp->if_ibytes += m->m_pkthdr.len;
ifp->if_ipackets++;
- netisr_dispatch(isr, top);
+ netisr_dispatch(isr, m);
return (0);
}
-------------- next part --------------
Index: if_tap.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_tap.c,v
retrieving revision 1.47
diff -u -r1.47 if_tap.c
--- if_tap.c 17 Sep 2004 03:55:50 -0000 1.47
+++ if_tap.c 17 Oct 2004 12:49:32 -0000
@@ -800,8 +800,8 @@
{
struct tap_softc *tp = dev->si_drv1;
struct ifnet *ifp = &tp->tap_if;
- struct mbuf *top = NULL, **mp = NULL, *m = NULL;
- int error = 0, tlen, mlen;
+ struct mbuf *m;
+ int error = 0;
TAPDEBUG("%s writting, minor = %#x\n",
ifp->if_xname, minor(dev));
@@ -815,42 +815,16 @@
return (EIO);
}
- tlen = uio->uio_resid;
- /* get a header mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (ENOBUFS);
- mlen = MHLEN;
-
- top = 0;
- mp = ⊤
- while ((error == 0) && (uio->uio_resid > 0)) {
- m->m_len = min(mlen, uio->uio_resid);
- error = uiomove(mtod(m, void *), m->m_len, uio);
- *mp = m;
- mp = &m->m_next;
- if (uio->uio_resid > 0) {
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- error = ENOBUFS;
- break;
- }
- mlen = MLEN;
- }
- }
- if (error) {
+ if ((m = m_uiotombuf(uio, M_DONTWAIT, 0)) == NULL) {
ifp->if_ierrors ++;
- if (top)
- m_freem(top);
return (error);
}
- top->m_pkthdr.len = tlen;
- top->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.rcvif = ifp;
/* Pass packet up to parent. */
- (*ifp->if_input)(ifp, top);
+ (*ifp->if_input)(ifp, m);
ifp->if_ipackets ++; /* ibytes are counted in parent */
return (0);
More information about the freebsd-current
mailing list