summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-01-18 21:09:34 +0000
committermav <mav@FreeBSD.org>2009-01-18 21:09:34 +0000
commit2ff507514a651a86347761c89dda40c80f8b687d (patch)
treee11c0a337047e9f6cd267252012da343bfd7b1b2 /sys/netgraph
parentdcb95080708721223062130a104f98b98afc08b5 (diff)
downloadFreeBSD-src-2ff507514a651a86347761c89dda40c80f8b687d.zip
FreeBSD-src-2ff507514a651a86347761c89dda40c80f8b687d.tar.gz
If source mbuf chain consists of only one mbuf, use it directly as source
buffer to avoid extra copying.
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_mppc.c85
1 files changed, 51 insertions, 34 deletions
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index 88ada5f..e934481 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -489,22 +489,29 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
if ((d->cfg.bits & MPPC_BIT) != 0) {
u_short flags = MPPC_MANDATORY_COMPRESS_FLAGS;
u_char *inbuf, *outbuf;
- int outlen, inlen;
+ int outlen, inlen, ina;
u_char *source, *dest;
u_long sourceCnt, destCnt;
int rtn;
/* Work with contiguous regions of memory. */
inlen = m->m_pkthdr.len;
- inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
- if (inbuf == NULL)
- goto err1;
- m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ if (m->m_next == NULL) {
+ inbuf = mtod(m, u_char *);
+ ina = 0;
+ } else {
+ inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
+ if (inbuf == NULL)
+ goto err1;
+ m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ ina = 1;
+ }
outlen = MPPC_MAX_BLOWUP(inlen);
outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (outbuf == NULL) {
- free(inbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
err1:
m_freem(m);
MPPC_InitCompressionHistory(d->history);
@@ -544,7 +551,8 @@ err1:
d->flushed = (rtn & MPPC_EXPANDED) != 0
|| (flags & MPPC_SAVE_HISTORY) == 0;
- free(inbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
free(outbuf, M_NETGRAPH_MPPC);
/* Check mbuf chain reload result. */
@@ -731,36 +739,43 @@ failed:
/* Decompress packet */
if ((header & MPPC_FLAG_COMPRESSED) != 0) {
int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS;
- u_char *decompbuf, *source, *dest;
+ u_char *inbuf, *outbuf;
+ int inlen, outlen, ina;
+ u_char *source, *dest;
u_long sourceCnt, destCnt;
- int decomplen, rtn;
- u_char *buf;
- int len;
+ int rtn;
/* Copy payload into a contiguous region of memory. */
- len = m->m_pkthdr.len;
- buf = malloc(len, M_NETGRAPH_MPPC, M_NOWAIT);
- if (buf == NULL) {
- m_freem(m);
- return (ENOMEM);
+ inlen = m->m_pkthdr.len;
+ if (m->m_next == NULL) {
+ inbuf = mtod(m, u_char *);
+ ina = 0;
+ } else {
+ inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
+ if (inbuf == NULL) {
+ m_freem(m);
+ return (ENOMEM);
+ }
+ m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ ina = 1;
}
- m_copydata(m, 0, len, (caddr_t)buf);
/* Allocate a buffer for decompressed data */
- decompbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY,
+ outbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY,
M_NETGRAPH_MPPC, M_NOWAIT);
- if (decompbuf == NULL) {
+ if (outbuf == NULL) {
m_freem(m);
- free(buf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
return (ENOMEM);
}
- decomplen = MPPC_DECOMP_BUFSIZE;
+ outlen = MPPC_DECOMP_BUFSIZE;
/* Prepare to decompress */
- source = buf;
- sourceCnt = len;
- dest = decompbuf;
- destCnt = decomplen;
+ source = inbuf;
+ sourceCnt = inlen;
+ dest = outbuf;
+ destCnt = outlen;
if ((header & MPPC_FLAG_RESTART) != 0)
flags |= MPPC_RESTART_HISTORY;
@@ -774,22 +789,24 @@ failed:
|| (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
log(LOG_ERR, "%s: decomp returned 0x%x",
__func__, rtn);
- free(buf, M_NETGRAPH_MPPC);
- free(decompbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
+ free(outbuf, M_NETGRAPH_MPPC);
goto failed;
}
/* Replace compressed data with decompressed data */
- free(buf, M_NETGRAPH_MPPC);
- len = decomplen - destCnt;
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
+ outlen -= destCnt;
- m_copyback(m, 0, len, (caddr_t)decompbuf);
- if (m->m_pkthdr.len < len) {
+ m_copyback(m, 0, outlen, (caddr_t)outbuf);
+ if (m->m_pkthdr.len < outlen) {
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);
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
+ free(outbuf, M_NETGRAPH_MPPC);
}
#endif
OpenPOWER on IntegriCloud