summaryrefslogtreecommitdiffstats
path: root/sys/netinet/libalias
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2008-06-01 17:52:40 +0000
committermav <mav@FreeBSD.org>2008-06-01 17:52:40 +0000
commit4dbba50d9d8658363b21d7a16cff9ae0b26eb2fd (patch)
treebe18127083a617e06e1966e1811dfafbc1e6e552 /sys/netinet/libalias
parent4d5dd9615437530955ff18d3eb5c4279a040788e (diff)
downloadFreeBSD-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.c44
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);
OpenPOWER on IntegriCloud