Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Oct 2004 16:54:11 +0400
From:      Gleb Smirnoff <glebius@freebsd.org>
To:        current@freebsd.org
Subject:   [TEST] tun(4) and tap(4) improvement
Message-ID:  <20041017125411.GA65842@cell.sick.ru>

next in thread | raw e-mail | index | archive | help

--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline

  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

--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=koi8-r
Content-Disposition: attachment; filename="tun.uiotombuf.diff"

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 = &top;
-	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);
 }
 

--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=koi8-r
Content-Disposition: attachment; filename="tap.uiotombuf.diff"

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 = &top;
-	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);

--MGYHOYXEY6WxJCY8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041017125411.GA65842>