diff options
author | mav <mav@FreeBSD.org> | 2008-06-01 17:52:40 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2008-06-01 17:52:40 +0000 |
commit | 4dbba50d9d8658363b21d7a16cff9ae0b26eb2fd (patch) | |
tree | be18127083a617e06e1966e1811dfafbc1e6e552 /sys/netinet/libalias | |
parent | 4d5dd9615437530955ff18d3eb5c4279a040788e (diff) | |
download | FreeBSD-src-4dbba50d9d8658363b21d7a16cff9ae0b26eb2fd.zip FreeBSD-src-4dbba50d9d8658363b21d7a16cff9ae0b26eb2fd.tar.gz |
Make m_megapullup() more intelligent:
- to increase performance do not reallocate mbuf when possible,
- to support up to 16K packets (was 2K max) use mbuf cluster of proper size.
This change depends on recent ng_nat and ip_fw_nat changes.
Diffstat (limited to 'sys/netinet/libalias')
-rw-r--r-- | sys/netinet/libalias/alias.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c index 59092c2..ea72c96 100644 --- a/sys/netinet/libalias/alias.c +++ b/sys/netinet/libalias/alias.c @@ -1656,29 +1656,49 @@ LibAliasUnLoadAllModule(void) * m_megapullup() - this function is a big hack. * Thankfully, it's only used in ng_nat and ipfw+nat. * - * It allocates an mbuf with cluster and copies the whole chain into cluster, - * so that it is all contiguous and the whole packet can be accessed via a - * plain (char *) pointer. This is required, because libalias doesn't know - * how to handle mbuf chains. + * It allocates an mbuf with cluster and copies the specified part of the chain + * into cluster, so that it is all contiguous and can be accessed via a plain + * (char *) pointer. This is required, because libalias doesn't know how to + * handle mbuf chains. * - * On success, m_megapullup returns an mbuf with cluster containing the input - * packet, on failure NULL. In both cases, the input packet is consumed. + * On success, m_megapullup returns an mbuf (possibly with cluster) containing + * the input packet, on failure NULL. The input packet is always consumed. */ struct mbuf * m_megapullup(struct mbuf *m, int len) { struct mbuf *mcl; - caddr_t cp; - if (len > MCLBYTES) + if (len > m->m_pkthdr.len) goto bad; - if ((mcl = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) + /* Do not reallocate packet if it is sequentional, + * writable and has some extra space for expansion. + * XXX: Constant 100bytes is completely empirical. */ +#define RESERVE 100 + if (m->m_next == NULL && M_WRITABLE(m) && M_TRAILINGSPACE(m) >= RESERVE) + return (m); + + if (len <= MCLBYTES - RESERVE) { + mcl = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + } else if (len < MJUM16BYTES) { + int size; + if (len <= MJUMPAGESIZE - RESERVE) { + size = MJUMPAGESIZE; + } else if (len <= MJUM9BYTES - RESERVE) { + size = MJUM9BYTES; + } else { + size = MJUM16BYTES; + }; + mcl = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size); + } else { + goto bad; + } + if (mcl == NULL) goto bad; - cp = mtod(mcl, caddr_t); - m_copydata(m, 0, len, cp); m_move_pkthdr(mcl, m); - mcl->m_len = mcl->m_pkthdr.len; + m_copydata(m, 0, len, mtod(mcl, caddr_t)); + mcl->m_len = mcl->m_pkthdr.len = len; m_freem(m); return (mcl); |