summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/ipsec_mbuf.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-03-15 21:11:11 +0000
committersam <sam@FreeBSD.org>2006-03-15 21:11:11 +0000
commitbf44b2399142c5c19044b8ec077d24f575b4837d (patch)
tree37e73e0739c8cc965722137151fcc6b048436675 /sys/netipsec/ipsec_mbuf.c
parent1be90b4811c008a8b0eaf81db44a8b3d0ecf04b9 (diff)
downloadFreeBSD-src-bf44b2399142c5c19044b8ec077d24f575b4837d.zip
FreeBSD-src-bf44b2399142c5c19044b8ec077d24f575b4837d.tar.gz
promote fast ipsec's m_clone routine for public use; it is renamed
m_unshare and the caller can now control how mbufs are allocated Reviewed by: andre, luigi, mlaier MFC after: 1 week
Diffstat (limited to 'sys/netipsec/ipsec_mbuf.c')
-rw-r--r--sys/netipsec/ipsec_mbuf.c149
1 files changed, 0 insertions, 149 deletions
diff --git a/sys/netipsec/ipsec_mbuf.c b/sys/netipsec/ipsec_mbuf.c
index ade7d33..b63a5af 100644
--- a/sys/netipsec/ipsec_mbuf.c
+++ b/sys/netipsec/ipsec_mbuf.c
@@ -43,155 +43,6 @@
#include <netipsec/ipsec.h>
/*
- * Create a writable copy of the mbuf chain. While doing this
- * we compact the chain with a goal of producing a chain with
- * at most two mbufs. The second mbuf in this chain is likely
- * to be a cluster. The primary purpose of this work is to create
- * a writable packet for encryption, compression, etc. The
- * secondary goal is to linearize the data so the data can be
- * passed to crypto hardware in the most efficient manner possible.
- */
-struct mbuf *
-m_clone(struct mbuf *m0)
-{
- struct mbuf *m, *mprev;
- struct mbuf *n, *mfirst, *mlast;
- int len, off;
-
- IPSEC_ASSERT(m0 != NULL, ("null mbuf"));
-
- mprev = NULL;
- for (m = m0; m != NULL; m = mprev->m_next) {
- /*
- * Regular mbufs are ignored unless there's a cluster
- * in front of it that we can use to coalesce. We do
- * the latter mainly so later clusters can be coalesced
- * also w/o having to handle them specially (i.e. convert
- * mbuf+cluster -> cluster). This optimization is heavily
- * influenced by the assumption that we're running over
- * Ethernet where MCLBYTES is large enough that the max
- * packet size will permit lots of coalescing into a
- * single cluster. This in turn permits efficient
- * crypto operations, especially when using hardware.
- */
- if ((m->m_flags & M_EXT) == 0) {
- if (mprev && (mprev->m_flags & M_EXT) &&
- m->m_len <= M_TRAILINGSPACE(mprev)) {
- /* XXX: this ignores mbuf types */
- memcpy(mtod(mprev, caddr_t) + mprev->m_len,
- mtod(m, caddr_t), m->m_len);
- mprev->m_len += m->m_len;
- mprev->m_next = m->m_next; /* unlink from chain */
- m_free(m); /* reclaim mbuf */
- newipsecstat.ips_mbcoalesced++;
- } else {
- mprev = m;
- }
- continue;
- }
- /*
- * Writable mbufs are left alone (for now).
- */
- if (M_WRITABLE(m)) {
- mprev = m;
- continue;
- }
-
- /*
- * Not writable, replace with a copy or coalesce with
- * the previous mbuf if possible (since we have to copy
- * it anyway, we try to reduce the number of mbufs and
- * clusters so that future work is easier).
- */
- IPSEC_ASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
- /* NB: we only coalesce into a cluster or larger */
- if (mprev != NULL && (mprev->m_flags & M_EXT) &&
- m->m_len <= M_TRAILINGSPACE(mprev)) {
- /* XXX: this ignores mbuf types */
- memcpy(mtod(mprev, caddr_t) + mprev->m_len,
- mtod(m, caddr_t), m->m_len);
- mprev->m_len += m->m_len;
- mprev->m_next = m->m_next; /* unlink from chain */
- m_free(m); /* reclaim mbuf */
- newipsecstat.ips_clcoalesced++;
- continue;
- }
-
- /*
- * Allocate new space to hold the copy...
- */
- /* XXX why can M_PKTHDR be set past the first mbuf? */
- if (mprev == NULL && (m->m_flags & M_PKTHDR)) {
- /*
- * NB: if a packet header is present we must
- * allocate the mbuf separately from any cluster
- * because M_MOVE_PKTHDR will smash the data
- * pointer and drop the M_EXT marker.
- */
- MGETHDR(n, M_DONTWAIT, m->m_type);
- if (n == NULL) {
- m_freem(m0);
- return (NULL);
- }
- M_MOVE_PKTHDR(n, m);
- MCLGET(n, M_DONTWAIT);
- if ((n->m_flags & M_EXT) == 0) {
- m_free(n);
- m_freem(m0);
- return (NULL);
- }
- } else {
- n = m_getcl(M_DONTWAIT, m->m_type, m->m_flags);
- if (n == NULL) {
- m_freem(m0);
- return (NULL);
- }
- }
- /*
- * ... and copy the data. We deal with jumbo mbufs
- * (i.e. m_len > MCLBYTES) by splitting them into
- * clusters. We could just malloc a buffer and make
- * it external but too many device drivers don't know
- * how to break up the non-contiguous memory when
- * doing DMA.
- */
- len = m->m_len;
- off = 0;
- mfirst = n;
- mlast = NULL;
- for (;;) {
- int cc = min(len, MCLBYTES);
- memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, cc);
- n->m_len = cc;
- if (mlast != NULL)
- mlast->m_next = n;
- mlast = n;
- newipsecstat.ips_clcopied++;
-
- len -= cc;
- if (len <= 0)
- break;
- off += cc;
-
- n = m_getcl(M_DONTWAIT, m->m_type, m->m_flags);
- if (n == NULL) {
- m_freem(mfirst);
- m_freem(m0);
- return (NULL);
- }
- }
- n->m_next = m->m_next;
- if (mprev == NULL)
- m0 = mfirst; /* new head of chain */
- else
- mprev->m_next = mfirst; /* replace old mbuf */
- m_free(m); /* release old mbuf */
- mprev = mfirst;
- }
- return (m0);
-}
-
-/*
* Make space for a new header of length hlen at skip bytes
* into the packet. When doing this we allocate new mbufs only
* when absolutely necessary. The mbuf where the new header
OpenPOWER on IntegriCloud