diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index 4dc9b1a43a..6c22eebf6c 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -9,12 +9,14 @@ SubDirCcFlags [ FDefines _KERNEL=1 KTR=1 ] ; Library libfreebsd_network.a : bus.c - busdma_machdep.c callout.c compat.c device.c + fbsd_busdma_x86.c + fbsd_ether.c + fbsd_if_media.c + fbsd_mbuf.c if.c - if_media.c mbuf.c mii.c mutex.c diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index a14f09ca98..ae1146c434 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -334,6 +334,7 @@ vtophys(vm_offset_t vaddr) return (unsigned long)pe.address; } + status_t init_compat_layer() { diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h b/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h new file mode 100644 index 0000000000..5fd99d6622 --- /dev/null +++ b/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 1982, 1986, 1988, 1993 + * The Regents of the University of California. 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, 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)mbuf.h 8.5 (Berkeley) 2/19/95 + * $FreeBSD: src/sys/sys/mbuf.h,v 1.170.2.6 2006/03/23 23:24:32 sam Exp $ + */ +#ifndef _FBSD_COMPAT_SYS_MBUF_FBSD_H_ +#define _FBSD_COMPAT_SYS_MBUF_FBSD_H_ + +/* + * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place + * an object of the specified size at the end of the mbuf, longword aligned. + */ +#define M_ALIGN(m, len) do { \ + (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \ +} while (0) + +/* + * As above, for mbufs allocated with m_gethdr/MGETHDR + * or initialized by M_COPY_PKTHDR. + */ +#define MH_ALIGN(m, len) do { \ + (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \ +} while (0) + + +/* +#define MEXT_IS_REF(m) (((m)->m_ext.ref_cnt != NULL) \ + && (*((m)->m_ext.ref_cnt) > 1)) + */ +#define MEXT_IS_REF(m) 0 + +/* + * Evaluate TRUE if it's safe to write to the mbuf m's data region (this + * can be both the local data payload, or an external buffer area, + * depending on whether M_EXT is set). + */ + +/* +#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && (!((m)->m_flags \ + & M_EXT) || !MEXT_IS_REF(m))) + */ +#define M_WRITABLE(m) (!((m)->m_flags & M_EXT) || !MEXT_IS_REF(m)) + +/* + * Compute the amount of space available + * before the current start of data in an mbuf. + * + * The M_WRITABLE() is a temporary, conservative safety measure: the burden + * of checking writability of the mbuf data area rests solely with the caller. + */ +#define M_LEADINGSPACE(m) \ + ((m)->m_flags & M_EXT ? \ + (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \ + (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ + (m)->m_data - (m)->m_dat) + +/* + * Arrange to prepend space of size plen to mbuf m. + * If a new mbuf must be allocated, how specifies whether to wait. + * If the allocation fails, the original mbuf chain is freed and m is + * set to NULL. + */ +#define M_PREPEND(m, plen, how) do { \ + struct mbuf **_mmp = &(m); \ + struct mbuf *_mm = *_mmp; \ + int _mplen = (plen); \ + int __mhow = (how); \ + \ + MBUF_CHECKSLEEP(how); \ + if (M_LEADINGSPACE(_mm) >= _mplen) { \ + _mm->m_data -= _mplen; \ + _mm->m_len += _mplen; \ + } else \ + _mm = m_prepend(_mm, _mplen, __mhow); \ + if (_mm != NULL && _mm->m_flags & M_PKTHDR) \ + _mm->m_pkthdr.len += _mplen; \ + *_mmp = _mm; \ +} while (0) + +#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf.h b/src/libs/compat/freebsd_network/compat/sys/mbuf.h index 5584e5fede..ed74c9331d 100644 --- a/src/libs/compat/freebsd_network/compat/sys/mbuf.h +++ b/src/libs/compat/freebsd_network/compat/sys/mbuf.h @@ -118,78 +118,11 @@ void m_clget(struct mbuf *m, int how); ("%s: no mbuf packet header!", __func__)) #define MBUF_CHECKSLEEP(how) do { } while (0) +#define MBTOM(how) (how) +extern int max_protohdr; -/* - * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place - * an object of the specified size at the end of the mbuf, longword aligned. - */ -#define M_ALIGN(m, len) do { \ - (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \ -} while (0) - -/* - * As above, for mbufs allocated with m_gethdr/MGETHDR - * or initialized by M_COPY_PKTHDR. - */ -#define MH_ALIGN(m, len) do { \ - (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \ -} while (0) - - -/* -#define MEXT_IS_REF(m) (((m)->m_ext.ref_cnt != NULL) \ - && (*((m)->m_ext.ref_cnt) > 1)) - */ -#define MEXT_IS_REF(m) 0 - -/* - * Evaluate TRUE if it's safe to write to the mbuf m's data region (this - * can be both the local data payload, or an external buffer area, - * depending on whether M_EXT is set). - */ - -/* -#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && (!((m)->m_flags \ - & M_EXT) || !MEXT_IS_REF(m))) - */ -#define M_WRITABLE(m) (!((m)->m_flags & M_EXT) || !MEXT_IS_REF(m)) - -/* - * Compute the amount of space available - * before the current start of data in an mbuf. - * - * The M_WRITABLE() is a temporary, conservative safety measure: the burden - * of checking writability of the mbuf data area rests solely with the caller. - */ -#define M_LEADINGSPACE(m) \ - ((m)->m_flags & M_EXT ? \ - (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \ - (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ - (m)->m_data - (m)->m_dat) - -/* - * Arrange to prepend space of size plen to mbuf m. - * If a new mbuf must be allocated, how specifies whether to wait. - * If the allocation fails, the original mbuf chain is freed and m is - * set to NULL. - */ -#define M_PREPEND(m, plen, how) do { \ - struct mbuf **_mmp = &(m); \ - struct mbuf *_mm = *_mmp; \ - int _mplen = (plen); \ - int __mhow = (how); \ - \ - MBUF_CHECKSLEEP(how); \ - if (M_LEADINGSPACE(_mm) >= _mplen) { \ - _mm->m_data -= _mplen; \ - _mm->m_len += _mplen; \ - } else \ - _mm = m_prepend(_mm, _mplen, __mhow); \ - if (_mm != NULL && _mm->m_flags & M_PKTHDR) \ - _mm->m_pkthdr.len += _mplen; \ - *_mmp = _mm; \ -} while (0) +#include #endif diff --git a/src/libs/compat/freebsd_network/compat/sys/types.h b/src/libs/compat/freebsd_network/compat/sys/types.h index a29de0df68..878876a913 100644 --- a/src/libs/compat/freebsd_network/compat/sys/types.h +++ b/src/libs/compat/freebsd_network/compat/sys/types.h @@ -1,6 +1,7 @@ #ifndef _FBSD_COMPAT_SYS_TYPES_H_ #define _FBSD_COMPAT_SYS_TYPES_H_ +#include #include typedef int boolean_t; diff --git a/src/libs/compat/freebsd_network/busdma_machdep.c b/src/libs/compat/freebsd_network/fbsd_busdma_x86.c similarity index 100% rename from src/libs/compat/freebsd_network/busdma_machdep.c rename to src/libs/compat/freebsd_network/fbsd_busdma_x86.c diff --git a/src/libs/compat/freebsd_network/fbsd_ether.c b/src/libs/compat/freebsd_network/fbsd_ether.c new file mode 100644 index 0000000000..6e661909d2 --- /dev/null +++ b/src/libs/compat/freebsd_network/fbsd_ether.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 1982, 1989, 1993 + * The Regents of the University of California. 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, 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.193.2.12 2006/08/28 02:54:14 thompsa Exp $ + */ + +#include +#include +#include + +#if 0 +/* + * This is for reference. We have a table-driven version + * of the little-endian crc32 generator, which is faster + * than the double-loop. + */ +uint32_t +ether_crc32_le(const uint8_t *buf, size_t len) +{ + size_t i; + uint32_t crc; + int bit; + uint8_t data; + + crc = 0xffffffff; /* initial value */ + + for (i = 0; i < len; i++) { + for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) + carry = (crc ^ data) & 1; + crc >>= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_LE); + } + + return (crc); +} +#else +uint32_t +ether_crc32_le(const uint8_t *buf, size_t len) +{ + static const uint32_t crctab[] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + size_t i; + uint32_t crc; + + crc = 0xffffffff; /* initial value */ + + for (i = 0; i < len; i++) { + crc ^= buf[i]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + } + + return (crc); +} +#endif + +uint32_t +ether_crc32_be(const uint8_t *buf, size_t len) +{ + size_t i; + uint32_t crc, carry; + int bit; + uint8_t data; + + crc = 0xffffffff; /* initial value */ + + for (i = 0; i < len; i++) { + for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) { + carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); + crc <<= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_BE) | carry; + } + } + + return (crc); +} + + +char * +ether_sprintf(const u_char *ap) +{ + static char etherbuf[18]; + snprintf(etherbuf, sizeof (etherbuf), + "%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned)ap[0], (unsigned)ap[1], (unsigned)ap[2], + (unsigned)ap[3], (unsigned)ap[4], (unsigned)ap[5]); + return (etherbuf); +} diff --git a/src/libs/compat/freebsd_network/if_media.c b/src/libs/compat/freebsd_network/fbsd_if_media.c similarity index 100% rename from src/libs/compat/freebsd_network/if_media.c rename to src/libs/compat/freebsd_network/fbsd_if_media.c diff --git a/src/libs/compat/freebsd_network/fbsd_mbuf.c b/src/libs/compat/freebsd_network/fbsd_mbuf.c new file mode 100644 index 0000000000..9a4b080e39 --- /dev/null +++ b/src/libs/compat/freebsd_network/fbsd_mbuf.c @@ -0,0 +1,406 @@ +/*- + * Copyright (c) 1982, 1986, 1988, 1991, 1993 + * The Regents of the University of California. 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, 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 + */ + +#include +#include + +/* + * Copy data from an mbuf chain starting "off" bytes from the beginning, + * continuing for "len" bytes, into the indicated buffer. + */ +void +m_copydata(const struct mbuf *m, int off, int len, caddr_t cp) +{ + u_int count; + + KASSERT(off >= 0, ("m_copydata, negative off %d", off)); + KASSERT(len >= 0, ("m_copydata, negative len %d", len)); + while (off > 0) { + KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain")); + if (off < m->m_len) + break; + off -= m->m_len; + m = m->m_next; + } + while (len > 0) { + KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain")); + count = min(m->m_len - off, len); + bcopy(mtod(m, caddr_t) + off, cp, count); + len -= count; + cp += count; + off = 0; + m = m->m_next; + } +} + + +/* + * Concatenate mbuf chain n to m. + * Both chains must be of the same type (e.g. MT_DATA). + * Any m_pkthdr is not updated. + */ +void +m_cat(struct mbuf *m, struct mbuf *n) +{ + while (m->m_next) + m = m->m_next; + while (n) { + if (m->m_flags & M_EXT || + m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) { + /* just join the two chains */ + m->m_next = n; + return; + } + /* splat the data from one into the other */ + bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, + (u_int)n->m_len); + m->m_len += n->m_len; + n = m_free(n); + } +} + + +u_int +m_length(struct mbuf *m0, struct mbuf **last) +{ + struct mbuf *m; + u_int len; + + len = 0; + for (m = m0; m != NULL; m = m->m_next) { + len += m->m_len; + if (m->m_next == NULL) + break; + } + if (last != NULL) + *last = m; + return (len); +} + + +u_int +m_fixhdr(struct mbuf *m0) +{ + u_int len; + + len = m_length(m0, NULL); + m0->m_pkthdr.len = len; + return (len); +} + + +static int +m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how) +{ + return 1; +} + + +/* + * Duplicate "from"'s mbuf pkthdr in "to". + * "from" must have M_PKTHDR set, and "to" must be empty. + * In particular, this does a deep copy of the packet tags. + */ +static int +m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how) +{ + MBUF_CHECKSLEEP(how); + /* to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); */ + to->m_flags = (to->m_flags & M_EXT); + if ((to->m_flags & M_EXT) == 0) + to->m_data = to->m_pktdat; + to->m_pkthdr = from->m_pkthdr; + /* SLIST_INIT(&to->m_pkthdr.tags); */ + return (m_tag_copy_chain(to, from, MBTOM(how))); +} + + +/* + * Defragment a mbuf chain, returning the shortest possible + * chain of mbufs and clusters. If allocation fails and + * this cannot be completed, NULL will be returned, but + * the passed in chain will be unchanged. Upon success, + * the original chain will be freed, and the new chain + * will be returned. + * + * If a non-packet header is passed in, the original + * mbuf (chain?) will be returned unharmed. + */ +struct mbuf * +m_defrag(struct mbuf *m0, int how) +{ + struct mbuf *m_new = NULL, *m_final = NULL; + int progress = 0, length; + + MBUF_CHECKSLEEP(how); + if (!(m0->m_flags & M_PKTHDR)) + return (m0); + + m_fixhdr(m0); /* Needed sanity check */ + + if (m0->m_pkthdr.len > MHLEN) + m_final = m_getcl(how, MT_DATA, M_PKTHDR); + else + m_final = m_gethdr(how, MT_DATA); + + if (m_final == NULL) + goto nospace; + + if (m_dup_pkthdr(m_final, m0, how) == 0) + goto nospace; + + m_new = m_final; + + while (progress < m0->m_pkthdr.len) { + length = m0->m_pkthdr.len - progress; + if (length > MCLBYTES) + length = MCLBYTES; + + if (m_new == NULL) { + if (length > MLEN) + m_new = m_getcl(how, MT_DATA, 0); + else + m_new = m_get(how, MT_DATA); + if (m_new == NULL) + goto nospace; + } + + m_copydata(m0, progress, length, mtod(m_new, caddr_t)); + progress += length; + m_new->m_len = length; + if (m_new != m_final) + m_cat(m_final, m_new); + m_new = NULL; + } + + m_freem(m0); + m0 = m_final; + return (m0); +nospace: + if (m_final) + m_freem(m_final); + return (NULL); +} + + +void +m_adj(struct mbuf *mp, int req_len) +{ + int len = req_len; + struct mbuf *m; + int count; + + if ((m = mp) == NULL) + return; + if (len >= 0) { + /* + * Trim from head. + */ + while (m != NULL && len > 0) { + if (m->m_len <= len) { + len -= m->m_len; + m->m_len = 0; + m = m->m_next; + } else { + m->m_len -= len; + m->m_data += len; + len = 0; + } + } + m = mp; + if (mp->m_flags & M_PKTHDR) + m->m_pkthdr.len -= (req_len - len); + } else { + /* + * Trim from tail. Scan the mbuf chain, + * calculating its length and finding the last mbuf. + * If the adjustment only affects this mbuf, then just + * adjust and return. Otherwise, rescan and truncate + * after the remaining size. + */ + len = -len; + count = 0; + for (;;) { + count += m->m_len; + if (m->m_next == (struct mbuf *)0) + break; + m = m->m_next; + } + if (m->m_len >= len) { + m->m_len -= len; + if (mp->m_flags & M_PKTHDR) + mp->m_pkthdr.len -= len; + return; + } + count -= len; + if (count < 0) + count = 0; + /* + * Correct length for chain is "count". + * Find the mbuf with last data, adjust its length, + * and toss data from remaining mbufs on chain. + */ + m = mp; + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len = count; + for (; m; m = m->m_next) { + if (m->m_len >= count) { + m->m_len = count; + if (m->m_next != NULL) { + m_freem(m->m_next); + m->m_next = NULL; + } + break; + } + count -= m->m_len; + } + } +} + + +/* + * Rearange an mbuf chain so that len bytes are contiguous + * and in the data area of an mbuf (so that mtod and dtom + * will work for a structure of size len). Returns the resulting + * mbuf chain on success, frees it and returns null on failure. + * If there is room, it will add up to max_protohdr-len extra bytes to the + * contiguous region in an attempt to avoid being called next time. + */ +struct mbuf * +m_pullup(struct mbuf *n, int len) +{ + struct mbuf *m; + int count; + int space; + + /* + * If first mbuf has no cluster, and has room for len bytes + * without shifting current data, pullup into it, + * otherwise allocate a new mbuf to prepend to the chain. + */ + if ((n->m_flags & M_EXT) == 0 && + n->m_data + len < &n->m_dat[MLEN] && n->m_next) { + if (n->m_len >= len) + return (n); + m = n; + n = n->m_next; + len -= m->m_len; + } else { + if (len > MHLEN) + goto bad; + MGET(m, M_DONTWAIT, n->m_type); + if (m == NULL) + goto bad; + m->m_len = 0; + if (n->m_flags & M_PKTHDR) + M_MOVE_PKTHDR(m, n); + } + space = &m->m_dat[MLEN] - (m->m_data + m->m_len); + do { + count = min(min(max(len, max_protohdr), space), n->m_len); + bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, + (u_int)count); + len -= count; + m->m_len += count; + n->m_len -= count; + space -= count; + if (n->m_len) + n->m_data += count; + else + n = m_free(n); + } while (len > 0 && n); + if (len > 0) { + (void) m_free(m); + goto bad; + } + m->m_next = n; + return (m); +bad: + m_freem(n); + return (NULL); +} + + +/* + * Lesser-used path for M_PREPEND: + * allocate new mbuf to prepend to chain, + * copy junk along. + */ +struct mbuf * +m_prepend(struct mbuf *m, int len, int how) +{ + struct mbuf *mn; + + if (m->m_flags & M_PKTHDR) + MGETHDR(mn, how, m->m_type); + else + MGET(mn, how, m->m_type); + if (mn == NULL) { + m_freem(m); + return (NULL); + } + if (m->m_flags & M_PKTHDR) + M_MOVE_PKTHDR(mn, m); + mn->m_next = m; + m = mn; + if (len < MHLEN) + MH_ALIGN(m, len); + m->m_len = len; + return (m); +} + + +/* + * "Move" mbuf pkthdr from "from" to "to". + * "from" must have M_PKTHDR set, and "to" must be empty. + */ +void +m_move_pkthdr(struct mbuf *to, struct mbuf *from) +{ +#ifdef MAC + /* + * XXXMAC: It could be this should also occur for non-MAC? + */ + if (to->m_flags & M_PKTHDR) + m_tag_delete_chain(to, NULL); +#endif + /* to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); */ + /* we don't have M_COPYFLAGS -hugo */ + to->m_flags = to->m_flags & M_EXT; + if ((to->m_flags & M_EXT) == 0) + to->m_data = to->m_pktdat; + to->m_pkthdr = from->m_pkthdr; /* especially tags */ + /* we don't have tags -hugo */ +#if 0 + SLIST_INIT(&from->m_pkthdr.tags); /* purge tags from src */ +#endif + from->m_flags &= ~M_PKTHDR; +} diff --git a/src/libs/compat/freebsd_network/if.c b/src/libs/compat/freebsd_network/if.c index bcd3fe9812..f1b8e71fea 100644 --- a/src/libs/compat/freebsd_network/if.c +++ b/src/libs/compat/freebsd_network/if.c @@ -192,80 +192,6 @@ ether_ifdetach(struct ifnet *ifp) } -#if 0 -/* - * This is for reference. We have a table-driven version - * of the little-endian crc32 generator, which is faster - * than the double-loop. - */ -uint32_t -ether_crc32_le(const uint8_t *buf, size_t len) -{ - size_t i; - uint32_t crc; - int bit; - uint8_t data; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) - carry = (crc ^ data) & 1; - crc >>= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_LE); - } - - return (crc); -} -#else -uint32_t -ether_crc32_le(const uint8_t *buf, size_t len) -{ - static const uint32_t crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - size_t i; - uint32_t crc; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - crc ^= buf[i]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - - return (crc); -} -#endif - -uint32_t -ether_crc32_be(const uint8_t *buf, size_t len) -{ - size_t i; - uint32_t crc, carry; - int bit; - uint8_t data; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) { - carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); - crc <<= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_BE) | carry; - } - } - - return (crc); -} - - int ether_ioctl(struct ifnet *ifp, int command, caddr_t data) { @@ -288,14 +214,3 @@ ether_ioctl(struct ifnet *ifp, int command, caddr_t data) return 0; } - -char * -ether_sprintf(const u_char *ap) -{ - static char etherbuf[18]; - snprintf(etherbuf, sizeof (etherbuf), - "%02lx:%02lx:%02lx:%02lx:%02lx:%02lx", - (uint32)ap[0], (uint32)ap[1], (uint32)ap[2], (uint32)ap[3], - (uint32)ap[4], (uint32)ap[5]); - return (etherbuf); -} diff --git a/src/libs/compat/freebsd_network/mbuf.c b/src/libs/compat/freebsd_network/mbuf.c index fd39af41fe..660a71ee53 100644 --- a/src/libs/compat/freebsd_network/mbuf.c +++ b/src/libs/compat/freebsd_network/mbuf.c @@ -19,13 +19,10 @@ #include #include - -#define MBTOM(how) (how) - static object_cache *sMBufCache; static object_cache *sChunkCache; -static const int max_protohdr = 40 + 20; /* ip6 + tcp */ +int max_protohdr = 40 + 20; /* ip6 + tcp */ static int