summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-01-18 19:25:36 +0000
committermav <mav@FreeBSD.org>2009-01-18 19:25:36 +0000
commit74ed22786b2388740d2f5bc730136ec510dcfac2 (patch)
treee258ed6671707a1c996eb707ec8d75e37a8f676d /sys/netgraph
parent963ae12224cd98dd95013e6649729f830eb6aa90 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/netgraph/ng_deflate.c41
-rw-r--r--sys/netgraph/ng_mppc.c45
-rw-r--r--sys/netgraph/ng_pred1.c43
3 files changed, 80 insertions, 49 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;
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index 5a6c302..88ada5f 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -470,6 +470,11 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
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 mbuf **datap)
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 mbuf **datap)
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
diff --git a/sys/netgraph/ng_pred1.c b/sys/netgraph/ng_pred1.c
index 981448e..5f01e88 100644
--- a/sys/netgraph/ng_pred1.c
+++ b/sys/netgraph/ng_pred1.c
@@ -400,11 +400,16 @@ ng_pred1_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 + 2));
- NG_FREE_M(m);
-
lenn = htons(inlen & 0x7FFF);
/* Compute FCS. */
@@ -437,12 +442,14 @@ ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
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 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);
@@ -485,13 +499,12 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
/* 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 mbuf *m, struct mbuf **resultp)
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++;
OpenPOWER on IntegriCloud