svn commit: r187405 - head/sys/netgraph

Alexander Motin mav at FreeBSD.org
Sun Jan 18 11:25:37 PST 2009


Author: mav
Date: Sun Jan 18 19:25:36 2009
New Revision: 187405
URL: http://svn.freebsd.org/changeset/base/187405

Log:
  Use m_unshare()+m_copyback() instead of m_freem()+m_devget() to keep
  original mbuf chain headers. It can be less efficient in some cases, but it
  looks better then mess of copying headers into the nonempty chain.

Modified:
  head/sys/netgraph/ng_deflate.c
  head/sys/netgraph/ng_mppc.c
  head/sys/netgraph/ng_pred1.c

Modified: head/sys/netgraph/ng_deflate.c
==============================================================================
--- head/sys/netgraph/ng_deflate.c	Sun Jan 18 19:20:10 2009	(r187404)
+++ head/sys/netgraph/ng_deflate.c	Sun Jan 18 19:25:36 2009	(r187405)
@@ -459,6 +459,13 @@ ng_deflate_compress(node_p node, struct 
 		return (ENOMEM);
 	}
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL) {
+		priv->stats.Errors++;
+		return (ENOMEM);
+	}
+
 	/* Work with contiguous regions of memory. */
 	m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
 	outlen = DEFLATE_BUF_SIZE;
@@ -497,19 +504,19 @@ ng_deflate_compress(node_p node, struct 
 		priv->stats.FramesUncomp++;
 		priv->stats.OutOctets+=inlen;
 	} else {
-		NG_FREE_M(m);
-
 		/* Install header. */
 		((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
 		((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
 
 		/* Return packet in an mbuf. */
-		*resultp = m_devget((caddr_t)priv->outbuf, outlen, 0, NULL,
-		    NULL);
-		if (*resultp == NULL) {
+		m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
+		if (m->m_pkthdr.len < outlen) {
+			m_freem(m);
 			priv->stats.Errors++;
 			return (ENOMEM);
-		};
+		} else if (outlen < m->m_pkthdr.len)
+			m_adj(m, outlen - m->m_pkthdr.len);
+		*resultp = m;
 		priv->stats.FramesComp++;
 		priv->stats.OutOctets+=outlen;
 	}
@@ -546,6 +553,13 @@ ng_deflate_decompress(node_p node, struc
 		return (ENOMEM);
 	}
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL) {
+		priv->stats.Errors++;
+		return (ENOMEM);
+	}
+
 	/* Work with contiguous regions of memory. */
 	m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
 
@@ -610,25 +624,24 @@ ng_deflate_decompress(node_p node, struc
 		/* Calculate resulting size. */
 		outlen -= priv->cx.avail_out;
 
-		NG_FREE_M(m);
-
 		/* Decompress protocol. */
 		if ((priv->outbuf[1] & 0x01) != 0) {
 			priv->outbuf[0] = 0;
 			/* Return packet in an mbuf. */
-			*resultp = m_devget((caddr_t)priv->outbuf, outlen, 0,
-			    NULL, NULL);
+			m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
 		} else {
 			outlen--;
 			/* Return packet in an mbuf. */
-			*resultp = m_devget((caddr_t)(priv->outbuf + 1),
-			    outlen, 0, NULL, NULL);
+			m_copyback(m, 0, outlen, (caddr_t)(priv->outbuf + 1));
 		}
-		if (*resultp == NULL) {
+		if (m->m_pkthdr.len < outlen) {
+			m_freem(m);
 			priv->stats.Errors++;
 			priv->seqnum = 0;
 			return (ENOMEM);
-		};
+		} else if (outlen < m->m_pkthdr.len)
+			m_adj(m, outlen - m->m_pkthdr.len);
+		*resultp = m;
 		priv->stats.FramesPlain++;
 		priv->stats.OutOctets+=outlen;
 

Modified: head/sys/netgraph/ng_mppc.c
==============================================================================
--- head/sys/netgraph/ng_mppc.c	Sun Jan 18 19:20:10 2009	(r187404)
+++ head/sys/netgraph/ng_mppc.c	Sun Jan 18 19:25:36 2009	(r187405)
@@ -470,6 +470,11 @@ ng_mppc_compress(node_p node, struct mbu
 	u_int16_t header;
 	struct mbuf *m = *datap;
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL)
+		return (ENOMEM);
+
 	/* Initialize */
 	header = d->cc;
 
@@ -529,8 +534,12 @@ err1:
 				header |= MPPC_FLAG_RESTART;  
 				
 			/* Replace m by the compresed one. */
-			m_freem(m);
-			m = m_devget((caddr_t)outbuf, outlen, 0, NULL, NULL);
+			m_copyback(m, 0, outlen, (caddr_t)outbuf);
+			if (m->m_pkthdr.len < outlen) {
+				m_freem(m);
+				m = NULL;
+			} else if (outlen < m->m_pkthdr.len)
+				m_adj(m, outlen - m->m_pkthdr.len);
 		}
 		d->flushed = (rtn & MPPC_EXPANDED) != 0
 		    || (flags & MPPC_SAVE_HISTORY) == 0;
@@ -538,7 +547,7 @@ err1:
 		free(inbuf, M_NETGRAPH_MPPC);
 		free(outbuf, M_NETGRAPH_MPPC);
 
-		/* Check m_devget() result. */
+		/* Check mbuf chain reload result. */
 		if (m == NULL) {
 			if (!d->flushed) {
 				MPPC_InitCompressionHistory(d->history);
@@ -557,18 +566,6 @@ err1:
 		/* Set header bits */
 		header |= MPPC_FLAG_ENCRYPTED;
 
-		/* We must own the mbuf chain exclusively to modify it. */
-		m = m_unshare(m, M_DONTWAIT);
-		if (m == NULL) {
-			if (!d->flushed) {
-#ifdef NETGRAPH_MPPC_COMPRESSION
-				MPPC_InitCompressionHistory(d->history);
-#endif
-				d->flushed = 1;
-			}
-			return (ENOMEM);
-		}
-
 		/* Update key if it's time */
 		if ((d->cfg.bits & MPPE_STATELESS) != 0
 		    || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
@@ -615,6 +612,11 @@ ng_mppc_decompress(node_p node, struct m
 	u_int numLost;
 	struct mbuf *m = *datap;
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL)
+		return (ENOMEM);
+
 	/* Pull off header */
 	if (m->m_pkthdr.len < MPPC_HDRLEN) {
 		m_freem(m);
@@ -694,11 +696,6 @@ ng_mppc_decompress(node_p node, struct m
 			    d->cfg.startkey, d->key, &d->rc4);
 		}
 
-		/* We must own the mbuf chain exclusively to modify it. */
-		m = m_unshare(m, M_DONTWAIT);
-		if (m == NULL)
-			return (ENOMEM);
-
 		/* Decrypt packet */
 		m1 = m;
 		while (m1 != NULL) {
@@ -786,8 +783,12 @@ failed:
 		free(buf, M_NETGRAPH_MPPC);
 		len = decomplen - destCnt;
 	
-		m_freem(m);
-		m = m_devget((caddr_t)decompbuf, len, 0, NULL, NULL);
+		m_copyback(m, 0, len, (caddr_t)decompbuf);
+		if (m->m_pkthdr.len < len) {
+			m_freem(m);
+			m = NULL;
+		} else if (len < m->m_pkthdr.len)
+			m_adj(m, len - m->m_pkthdr.len);
 		free(decompbuf, M_NETGRAPH_MPPC);
 	}
 #endif

Modified: head/sys/netgraph/ng_pred1.c
==============================================================================
--- head/sys/netgraph/ng_pred1.c	Sun Jan 18 19:20:10 2009	(r187404)
+++ head/sys/netgraph/ng_pred1.c	Sun Jan 18 19:25:36 2009	(r187405)
@@ -400,11 +400,16 @@ ng_pred1_compress(node_p node, struct mb
 		return (ENOMEM);
 	}
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL) {
+		priv->stats.Errors++;
+		return (ENOMEM);
+	}
+
 	/* Work with contiguous regions of memory. */
 	m_copydata(m, 0, inlen, (caddr_t)(priv->inbuf + 2));
 
-	NG_FREE_M(m);
-
 	lenn = htons(inlen & 0x7FFF);
 
 	/* Compute FCS. */
@@ -437,12 +442,14 @@ ng_pred1_compress(node_p node, struct mb
 	outlen += 2;
 
 	/* Return packet in an mbuf. */
-	*resultp = m_devget((caddr_t)out, outlen, 0, NULL, NULL);
-	if (*resultp == NULL) {
-	    priv->stats.Errors++;
-	    return (ENOMEM);
-	};
-
+	m_copyback(m, 0, outlen, (caddr_t)out);
+	if (m->m_pkthdr.len < outlen) {
+		m_freem(m);
+		priv->stats.Errors++;
+		return (ENOMEM);
+	} else if (outlen < m->m_pkthdr.len)
+		m_adj(m, outlen - m->m_pkthdr.len);
+	*resultp = m;
 	priv->stats.OutOctets += outlen;
 
 	return (0);
@@ -471,6 +478,13 @@ ng_pred1_decompress(node_p node, struct 
 		return (ENOMEM);
 	}
 
+	/* We must own the mbuf chain exclusively to modify it. */
+	m = m_unshare(m, M_DONTWAIT);
+	if (m == NULL) {
+		priv->stats.Errors++;
+		return (ENOMEM);
+	}
+
 	/* Work with contiguous regions of memory. */
 	m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
 
@@ -485,13 +499,12 @@ ng_pred1_decompress(node_p node, struct 
 
 	/* Is data compressed or not really? */
 	if (cf) {
-		NG_FREE_M(m);
-
 		priv->stats.FramesComp++;
 		len1 = Pred1Decompress(node, priv->inbuf + 2, priv->outbuf,
 		    inlen - 4, PRED1_BUF_SIZE);
 		if (len != len1) {
 			/* Error is detected. Send reset request */
+			m_freem(m);
 			priv->stats.Errors++;
 			log(LOG_NOTICE, "ng_pred1: Comp length error (%d) "
 			    "--> len (%d)\n", len, len1);
@@ -510,17 +523,21 @@ ng_pred1_decompress(node_p node, struct 
 		fcs = Crc16(fcs, priv->inbuf + inlen - 2, 2);
 
 		if (fcs != PPP_GOODFCS) {
+			m_freem(m);
 			priv->stats.Errors++;
 	    		log(LOG_NOTICE, "ng_pred1: Pred1: Bad CRC-16\n");
 			return (EIO);
 		}
 
 		/* Return packet in an mbuf. */
-		*resultp = m_devget((caddr_t)priv->outbuf, len, 0, NULL, NULL);
-		if (*resultp == NULL) {
+		m_copyback(m, 0, len, (caddr_t)priv->outbuf);
+		if (m->m_pkthdr.len < len) {
+			m_freem(m);
 			priv->stats.Errors++;
 			return (ENOMEM);
-		};
+		} else if (len < m->m_pkthdr.len)
+			m_adj(m, len - m->m_pkthdr.len);
+		*resultp = m;
 
 	} else {
 		priv->stats.FramesUncomp++;


More information about the svn-src-head mailing list