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.
This commit is contained in:
Alexander Motin 2009-01-18 19:25:36 +00:00
parent b51ba332bb
commit e4651e0595
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187405
3 changed files with 80 additions and 49 deletions

View File

@ -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;

View File

@ -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 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
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 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
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 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
/* 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 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
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

View File

@ -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++;