diff options
author | mav <mav@FreeBSD.org> | 2009-01-18 19:25:36 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-01-18 19:25:36 +0000 |
commit | 74ed22786b2388740d2f5bc730136ec510dcfac2 (patch) | |
tree | e258ed6671707a1c996eb707ec8d75e37a8f676d /sys/netgraph/ng_deflate.c | |
parent | 963ae12224cd98dd95013e6649729f830eb6aa90 (diff) | |
download | FreeBSD-src-74ed22786b2388740d2f5bc730136ec510dcfac2.zip FreeBSD-src-74ed22786b2388740d2f5bc730136ec510dcfac2.tar.gz |
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.
Diffstat (limited to 'sys/netgraph/ng_deflate.c')
-rw-r--r-- | sys/netgraph/ng_deflate.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/sys/netgraph/ng_deflate.c b/sys/netgraph/ng_deflate.c index 84609e3..b248a83 100644 --- a/sys/netgraph/ng_deflate.c +++ b/sys/netgraph/ng_deflate.c @@ -459,6 +459,13 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp) 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 mbuf *m, struct mbuf **resultp) 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, struct mbuf *m, struct mbuf **resultp) 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, struct mbuf *m, struct mbuf **resultp) /* 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; |