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


More information about the freebsd-current mailing list