diff --git a/src/libs/compat/freebsd11_network/Jamfile b/src/libs/compat/freebsd11_network/Jamfile index 7410856b61..a91c44c88a 100644 --- a/src/libs/compat/freebsd11_network/Jamfile +++ b/src/libs/compat/freebsd11_network/Jamfile @@ -26,6 +26,7 @@ KernelStaticLibrary libfreebsd11_network.a : fbsd_busdma_x86.c fbsd_ether.c fbsd_if_media.c + fbsd_kern_mbuf.c fbsd_uipc_mbuf.c fbsd_uipc_mbuf2.c fbsd_mii.c diff --git a/src/libs/compat/freebsd11_network/compat/sys/errno.h b/src/libs/compat/freebsd11_network/compat/sys/errno.h index fd307ce311..34b559f3f1 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/errno.h +++ b/src/libs/compat/freebsd11_network/compat/sys/errno.h @@ -9,6 +9,8 @@ #include +#define EDOOFUS EINVAL + /* pseudo-errors returned inside freebsd compat layer to modify return to process */ #define ERESTART (B_ERRORS_END + 1) /* restart syscall */ #define EJUSTRETURN (B_ERRORS_END + 2) /* don't modify regs, just return */ diff --git a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h index 76aa89ab12..2d2636a9ed 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h +++ b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h @@ -70,6 +70,8 @@ #define MGET(m, how, type) ((m) = m_get((how), (type))) #define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) #define MCLGET(m, how) m_clget((m), (how)) +#define m_getm(m, len, how, type) \ + m_getm2((m), (len), (how), (type), M_PKTHDR) #define mtod(m, type) ((type)((m)->m_data)) @@ -216,6 +218,7 @@ struct mbuf* m_free(struct mbuf*); void m_freem(struct mbuf*); struct mbuf* m_get(int, short); struct mbuf* m_get2(int size, int how, short type, int flags); +struct mbuf * m_getm2(struct mbuf *m, int len, int how, short type, int flags); struct mbuf* m_gethdr(int, short); struct mbuf* m_getjcl(int, short, int, int); u_int m_length(struct mbuf*, struct mbuf**); diff --git a/src/libs/compat/freebsd11_network/fbsd_kern_mbuf.c b/src/libs/compat/freebsd11_network/fbsd_kern_mbuf.c new file mode 100644 index 0000000000..ee972f5dc3 --- /dev/null +++ b/src/libs/compat/freebsd11_network/fbsd_kern_mbuf.c @@ -0,0 +1,97 @@ +/*! NOTE: Most kern_mbuf functions are implemented by our mbuf.c; however, + * a certain few non-allocation-related ones which we can copy wholesale + * from FreeBSD live here. */ +/*- + * Copyright (c) 2004, 2005, + * Bosko Milekic . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +/* + * Allocate a given length worth of mbufs and/or clusters (whatever fits + * best) and return a pointer to the top of the allocated chain. If an + * existing mbuf chain is provided, then we will append the new chain + * to the existing one but still return the top of the newly allocated + * chain. + */ +struct mbuf * +m_getm2(struct mbuf *m, int len, int how, short type, int flags) +{ + struct mbuf *mb, *nm = NULL, *mtail = NULL; + + KASSERT(len >= 0, ("%s: len is < 0", __func__)); + + /* Validate flags. */ + flags &= (M_PKTHDR | M_EOR); + + /* Packet header mbuf must be first in chain. */ + if ((flags & M_PKTHDR) && m != NULL) + flags &= ~M_PKTHDR; + + /* Loop and append maximum sized mbufs to the chain tail. */ + while (len > 0) { + if (len > MCLBYTES) + mb = m_getjcl(how, type, (flags & M_PKTHDR), + MJUMPAGESIZE); + else if (len >= MINCLSIZE) + mb = m_getcl(how, type, (flags & M_PKTHDR)); + else if (flags & M_PKTHDR) + mb = m_gethdr(how, type); + else + mb = m_get(how, type); + + /* Fail the whole operation if one mbuf can't be allocated. */ + if (mb == NULL) { + if (nm != NULL) + m_freem(nm); + return (NULL); + } + + /* Book keeping. */ + len -= M_SIZE(mb); + if (mtail != NULL) + mtail->m_next = mb; + else + nm = mb; + mtail = mb; + flags &= ~M_PKTHDR; /* Only valid on the first mbuf. */ + } + if (flags & M_EOR) + mtail->m_flags |= M_EOR; /* Only valid on the last mbuf. */ + + /* If mbuf was supplied, append new chain to the end of it. */ + if (m != NULL) { + for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next) + ; + mtail->m_next = nm; + mtail->m_flags &= ~M_EOR; + } else + m = nm; + + return (m); +} +