[BACK]Return to uipc_mbuf.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/uipc_mbuf.c, Revision 1.13

1.13    ! cgd         1: /*     $NetBSD: uipc_mbuf.c,v 1.12 1994/09/28 00:44:30 deraadt Exp $   */
1.10      cgd         2:
1.1       cgd         3: /*
1.9       mycroft     4:  * Copyright (c) 1982, 1986, 1988, 1991, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Berkeley and its contributors.
                     19:  * 4. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
1.10      cgd        35:  *     @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
1.1       cgd        36:  */
                     37:
1.6       mycroft    38: #include <sys/param.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/malloc.h>
1.9       mycroft    42: #include <sys/map.h>
1.1       cgd        43: #define MBTYPES
1.6       mycroft    44: #include <sys/mbuf.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/syslog.h>
                     47: #include <sys/domain.h>
                     48: #include <sys/protosw.h>
                     49:
                     50: #include <vm/vm.h>
1.1       cgd        51:
                     52: extern vm_map_t mb_map;
                     53: struct mbuf *mbutl;
                     54: char   *mclrefcnt;
                     55:
1.4       jtc        56: void
1.1       cgd        57: mbinit()
                     58: {
                     59:        int s;
                     60:
                     61:        s = splimp();
1.12      deraadt    62:        if (m_clalloc(max(4096/CLBYTES, 1), M_DONTWAIT) == 0)
1.1       cgd        63:                goto bad;
                     64:        splx(s);
                     65:        return;
                     66: bad:
                     67:        panic("mbinit");
                     68: }
                     69:
                     70: /*
                     71:  * Allocate some number of mbuf clusters
                     72:  * and place on cluster free list.
                     73:  * Must be called at splimp.
                     74:  */
                     75: /* ARGSUSED */
1.5       cgd        76: m_clalloc(ncl, nowait)
1.1       cgd        77:        register int ncl;
1.9       mycroft    78:        int nowait;
1.1       cgd        79: {
1.9       mycroft    80:        static int logged;
1.1       cgd        81:        register caddr_t p;
                     82:        register int i;
1.9       mycroft    83:        int npg;
1.1       cgd        84:
                     85:        npg = ncl * CLSIZE;
1.5       cgd        86:        p = (caddr_t)kmem_malloc(mb_map, ctob(npg), !nowait);
1.1       cgd        87:        if (p == NULL) {
                     88:                if (logged == 0) {
                     89:                        logged++;
                     90:                        log(LOG_ERR, "mb_map full\n");
                     91:                }
                     92:                return (0);
                     93:        }
                     94:        ncl = ncl * CLBYTES / MCLBYTES;
                     95:        for (i = 0; i < ncl; i++) {
                     96:                ((union mcluster *)p)->mcl_next = mclfree;
                     97:                mclfree = (union mcluster *)p;
                     98:                p += MCLBYTES;
                     99:                mbstat.m_clfree++;
                    100:        }
                    101:        mbstat.m_clusters += ncl;
                    102:        return (1);
                    103: }
                    104:
                    105: /*
                    106:  * When MGET failes, ask protocols to free space when short of memory,
                    107:  * then re-attempt to allocate an mbuf.
                    108:  */
                    109: struct mbuf *
                    110: m_retry(i, t)
                    111:        int i, t;
                    112: {
                    113:        register struct mbuf *m;
                    114:
                    115:        m_reclaim();
                    116: #define m_retry(i, t)  (struct mbuf *)0
                    117:        MGET(m, i, t);
                    118: #undef m_retry
                    119:        return (m);
                    120: }
                    121:
                    122: /*
                    123:  * As above; retry an MGETHDR.
                    124:  */
                    125: struct mbuf *
                    126: m_retryhdr(i, t)
                    127:        int i, t;
                    128: {
                    129:        register struct mbuf *m;
                    130:
                    131:        m_reclaim();
                    132: #define m_retryhdr(i, t) (struct mbuf *)0
                    133:        MGETHDR(m, i, t);
                    134: #undef m_retryhdr
                    135:        return (m);
                    136: }
                    137:
                    138: m_reclaim()
                    139: {
                    140:        register struct domain *dp;
                    141:        register struct protosw *pr;
                    142:        int s = splimp();
                    143:
                    144:        for (dp = domains; dp; dp = dp->dom_next)
                    145:                for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
                    146:                        if (pr->pr_drain)
                    147:                                (*pr->pr_drain)();
                    148:        splx(s);
                    149:        mbstat.m_drain++;
                    150: }
                    151:
                    152: /*
                    153:  * Space allocation routines.
                    154:  * These are also available as macros
                    155:  * for critical paths.
                    156:  */
                    157: struct mbuf *
1.5       cgd       158: m_get(nowait, type)
                    159:        int nowait, type;
1.1       cgd       160: {
                    161:        register struct mbuf *m;
                    162:
1.5       cgd       163:        MGET(m, nowait, type);
1.1       cgd       164:        return (m);
                    165: }
                    166:
                    167: struct mbuf *
1.5       cgd       168: m_gethdr(nowait, type)
                    169:        int nowait, type;
1.1       cgd       170: {
                    171:        register struct mbuf *m;
                    172:
1.5       cgd       173:        MGETHDR(m, nowait, type);
1.1       cgd       174:        return (m);
                    175: }
                    176:
                    177: struct mbuf *
1.5       cgd       178: m_getclr(nowait, type)
                    179:        int nowait, type;
1.1       cgd       180: {
                    181:        register struct mbuf *m;
                    182:
1.5       cgd       183:        MGET(m, nowait, type);
1.1       cgd       184:        if (m == 0)
                    185:                return (0);
                    186:        bzero(mtod(m, caddr_t), MLEN);
                    187:        return (m);
                    188: }
                    189:
                    190: struct mbuf *
                    191: m_free(m)
                    192:        struct mbuf *m;
                    193: {
                    194:        register struct mbuf *n;
                    195:
                    196:        MFREE(m, n);
                    197:        return (n);
                    198: }
                    199:
1.9       mycroft   200: void
1.1       cgd       201: m_freem(m)
                    202:        register struct mbuf *m;
                    203: {
                    204:        register struct mbuf *n;
                    205:
                    206:        if (m == NULL)
                    207:                return;
                    208:        do {
                    209:                MFREE(m, n);
                    210:        } while (m = n);
                    211: }
                    212:
                    213: /*
                    214:  * Mbuffer utility routines.
                    215:  */
                    216:
                    217: /*
                    218:  * Lesser-used path for M_PREPEND:
                    219:  * allocate new mbuf to prepend to chain,
                    220:  * copy junk along.
                    221:  */
                    222: struct mbuf *
1.9       mycroft   223: m_prepend(m, len, how)
1.1       cgd       224:        register struct mbuf *m;
1.9       mycroft   225:        int len, how;
1.1       cgd       226: {
                    227:        struct mbuf *mn;
                    228:
1.9       mycroft   229:        MGET(mn, how, m->m_type);
1.1       cgd       230:        if (mn == (struct mbuf *)NULL) {
                    231:                m_freem(m);
                    232:                return ((struct mbuf *)NULL);
                    233:        }
                    234:        if (m->m_flags & M_PKTHDR) {
                    235:                M_COPY_PKTHDR(mn, m);
                    236:                m->m_flags &= ~M_PKTHDR;
                    237:        }
                    238:        mn->m_next = m;
                    239:        m = mn;
                    240:        if (len < MHLEN)
                    241:                MH_ALIGN(m, len);
                    242:        m->m_len = len;
                    243:        return (m);
                    244: }
                    245:
                    246: /*
                    247:  * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
                    248:  * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
                    249:  * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
                    250:  */
                    251: int MCFail;
                    252:
                    253: struct mbuf *
                    254: m_copym(m, off0, len, wait)
                    255:        register struct mbuf *m;
                    256:        int off0, wait;
                    257:        register int len;
                    258: {
                    259:        register struct mbuf *n, **np;
                    260:        register int off = off0;
                    261:        struct mbuf *top;
                    262:        int copyhdr = 0;
                    263:
                    264:        if (off < 0 || len < 0)
                    265:                panic("m_copym");
                    266:        if (off == 0 && m->m_flags & M_PKTHDR)
                    267:                copyhdr = 1;
                    268:        while (off > 0) {
                    269:                if (m == 0)
                    270:                        panic("m_copym");
                    271:                if (off < m->m_len)
                    272:                        break;
                    273:                off -= m->m_len;
                    274:                m = m->m_next;
                    275:        }
                    276:        np = &top;
                    277:        top = 0;
                    278:        while (len > 0) {
                    279:                if (m == 0) {
                    280:                        if (len != M_COPYALL)
                    281:                                panic("m_copym");
                    282:                        break;
                    283:                }
                    284:                MGET(n, wait, m->m_type);
                    285:                *np = n;
                    286:                if (n == 0)
                    287:                        goto nospace;
                    288:                if (copyhdr) {
                    289:                        M_COPY_PKTHDR(n, m);
                    290:                        if (len == M_COPYALL)
                    291:                                n->m_pkthdr.len -= off0;
                    292:                        else
                    293:                                n->m_pkthdr.len = len;
                    294:                        copyhdr = 0;
                    295:                }
1.9       mycroft   296:                n->m_len = min(len, m->m_len - off);
1.1       cgd       297:                if (m->m_flags & M_EXT) {
                    298:                        n->m_data = m->m_data + off;
                    299:                        mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
                    300:                        n->m_ext = m->m_ext;
                    301:                        n->m_flags |= M_EXT;
                    302:                } else
                    303:                        bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
                    304:                            (unsigned)n->m_len);
                    305:                if (len != M_COPYALL)
                    306:                        len -= n->m_len;
                    307:                off = 0;
                    308:                m = m->m_next;
                    309:                np = &n->m_next;
                    310:        }
                    311:        if (top == 0)
                    312:                MCFail++;
                    313:        return (top);
                    314: nospace:
                    315:        m_freem(top);
                    316:        MCFail++;
                    317:        return (0);
                    318: }
                    319:
                    320: /*
                    321:  * Copy data from an mbuf chain starting "off" bytes from the beginning,
                    322:  * continuing for "len" bytes, into the indicated buffer.
                    323:  */
                    324: m_copydata(m, off, len, cp)
                    325:        register struct mbuf *m;
                    326:        register int off;
                    327:        register int len;
                    328:        caddr_t cp;
                    329: {
                    330:        register unsigned count;
                    331:
                    332:        if (off < 0 || len < 0)
                    333:                panic("m_copydata");
                    334:        while (off > 0) {
                    335:                if (m == 0)
                    336:                        panic("m_copydata");
                    337:                if (off < m->m_len)
                    338:                        break;
                    339:                off -= m->m_len;
                    340:                m = m->m_next;
                    341:        }
                    342:        while (len > 0) {
                    343:                if (m == 0)
                    344:                        panic("m_copydata");
1.9       mycroft   345:                count = min(m->m_len - off, len);
1.1       cgd       346:                bcopy(mtod(m, caddr_t) + off, cp, count);
                    347:                len -= count;
                    348:                cp += count;
                    349:                off = 0;
                    350:                m = m->m_next;
                    351:        }
                    352: }
                    353:
                    354: /*
                    355:  * Concatenate mbuf chain n to m.
                    356:  * Both chains must be of the same type (e.g. MT_DATA).
                    357:  * Any m_pkthdr is not updated.
                    358:  */
                    359: m_cat(m, n)
                    360:        register struct mbuf *m, *n;
                    361: {
                    362:        while (m->m_next)
                    363:                m = m->m_next;
                    364:        while (n) {
                    365:                if (m->m_flags & M_EXT ||
                    366:                    m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
                    367:                        /* just join the two chains */
                    368:                        m->m_next = n;
                    369:                        return;
                    370:                }
                    371:                /* splat the data from one into the other */
                    372:                bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
                    373:                    (u_int)n->m_len);
                    374:                m->m_len += n->m_len;
                    375:                n = m_free(n);
                    376:        }
                    377: }
                    378:
1.11      mycroft   379: void
1.1       cgd       380: m_adj(mp, req_len)
                    381:        struct mbuf *mp;
1.8       deraadt   382:        int req_len;
1.1       cgd       383: {
                    384:        register int len = req_len;
                    385:        register struct mbuf *m;
                    386:        register count;
                    387:
                    388:        if ((m = mp) == NULL)
                    389:                return;
                    390:        if (len >= 0) {
                    391:                /*
                    392:                 * Trim from head.
                    393:                 */
                    394:                while (m != NULL && len > 0) {
                    395:                        if (m->m_len <= len) {
                    396:                                len -= m->m_len;
                    397:                                m->m_len = 0;
                    398:                                m = m->m_next;
                    399:                        } else {
                    400:                                m->m_len -= len;
                    401:                                m->m_data += len;
                    402:                                len = 0;
                    403:                        }
                    404:                }
                    405:                m = mp;
                    406:                if (mp->m_flags & M_PKTHDR)
                    407:                        m->m_pkthdr.len -= (req_len - len);
                    408:        } else {
                    409:                /*
                    410:                 * Trim from tail.  Scan the mbuf chain,
                    411:                 * calculating its length and finding the last mbuf.
                    412:                 * If the adjustment only affects this mbuf, then just
                    413:                 * adjust and return.  Otherwise, rescan and truncate
                    414:                 * after the remaining size.
                    415:                 */
                    416:                len = -len;
                    417:                count = 0;
                    418:                for (;;) {
                    419:                        count += m->m_len;
                    420:                        if (m->m_next == (struct mbuf *)0)
                    421:                                break;
                    422:                        m = m->m_next;
                    423:                }
                    424:                if (m->m_len >= len) {
                    425:                        m->m_len -= len;
1.8       deraadt   426:                        if (mp->m_flags & M_PKTHDR)
                    427:                                mp->m_pkthdr.len -= len;
1.1       cgd       428:                        return;
                    429:                }
                    430:                count -= len;
                    431:                if (count < 0)
                    432:                        count = 0;
                    433:                /*
                    434:                 * Correct length for chain is "count".
                    435:                 * Find the mbuf with last data, adjust its length,
                    436:                 * and toss data from remaining mbufs on chain.
                    437:                 */
                    438:                m = mp;
                    439:                if (m->m_flags & M_PKTHDR)
                    440:                        m->m_pkthdr.len = count;
                    441:                for (; m; m = m->m_next) {
                    442:                        if (m->m_len >= count) {
                    443:                                m->m_len = count;
                    444:                                break;
                    445:                        }
                    446:                        count -= m->m_len;
                    447:                }
                    448:                while (m = m->m_next)
                    449:                        m->m_len = 0;
                    450:        }
                    451: }
                    452:
                    453: /*
                    454:  * Rearange an mbuf chain so that len bytes are contiguous
                    455:  * and in the data area of an mbuf (so that mtod and dtom
                    456:  * will work for a structure of size len).  Returns the resulting
                    457:  * mbuf chain on success, frees it and returns null on failure.
                    458:  * If there is room, it will add up to max_protohdr-len extra bytes to the
                    459:  * contiguous region in an attempt to avoid being called next time.
                    460:  */
                    461: int MPFail;
                    462:
                    463: struct mbuf *
                    464: m_pullup(n, len)
                    465:        register struct mbuf *n;
                    466:        int len;
                    467: {
                    468:        register struct mbuf *m;
                    469:        register int count;
                    470:        int space;
                    471:
                    472:        /*
                    473:         * If first mbuf has no cluster, and has room for len bytes
                    474:         * without shifting current data, pullup into it,
                    475:         * otherwise allocate a new mbuf to prepend to the chain.
                    476:         */
                    477:        if ((n->m_flags & M_EXT) == 0 &&
                    478:            n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
                    479:                if (n->m_len >= len)
                    480:                        return (n);
                    481:                m = n;
                    482:                n = n->m_next;
                    483:                len -= m->m_len;
                    484:        } else {
                    485:                if (len > MHLEN)
                    486:                        goto bad;
                    487:                MGET(m, M_DONTWAIT, n->m_type);
                    488:                if (m == 0)
                    489:                        goto bad;
                    490:                m->m_len = 0;
                    491:                if (n->m_flags & M_PKTHDR) {
                    492:                        M_COPY_PKTHDR(m, n);
                    493:                        n->m_flags &= ~M_PKTHDR;
                    494:                }
                    495:        }
                    496:        space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
                    497:        do {
                    498:                count = min(min(max(len, max_protohdr), space), n->m_len);
                    499:                bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
                    500:                  (unsigned)count);
                    501:                len -= count;
                    502:                m->m_len += count;
                    503:                n->m_len -= count;
                    504:                space -= count;
                    505:                if (n->m_len)
                    506:                        n->m_data += count;
                    507:                else
                    508:                        n = m_free(n);
                    509:        } while (len > 0 && n);
                    510:        if (len > 0) {
                    511:                (void) m_free(m);
                    512:                goto bad;
                    513:        }
                    514:        m->m_next = n;
                    515:        return (m);
                    516: bad:
                    517:        m_freem(n);
                    518:        MPFail++;
                    519:        return (0);
1.9       mycroft   520: }
                    521:
                    522: /*
                    523:  * Partition an mbuf chain in two pieces, returning the tail --
                    524:  * all but the first len0 bytes.  In case of failure, it returns NULL and
                    525:  * attempts to restore the chain to its original state.
                    526:  */
                    527: struct mbuf *
                    528: m_split(m0, len0, wait)
                    529:        register struct mbuf *m0;
                    530:        int len0, wait;
                    531: {
                    532:        register struct mbuf *m, *n;
                    533:        unsigned len = len0, remain;
                    534:
                    535:        for (m = m0; m && len > m->m_len; m = m->m_next)
                    536:                len -= m->m_len;
                    537:        if (m == 0)
                    538:                return (0);
                    539:        remain = m->m_len - len;
                    540:        if (m0->m_flags & M_PKTHDR) {
                    541:                MGETHDR(n, wait, m0->m_type);
                    542:                if (n == 0)
                    543:                        return (0);
                    544:                n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
                    545:                n->m_pkthdr.len = m0->m_pkthdr.len - len0;
                    546:                m0->m_pkthdr.len = len0;
                    547:                if (m->m_flags & M_EXT)
                    548:                        goto extpacket;
                    549:                if (remain > MHLEN) {
                    550:                        /* m can't be the lead packet */
                    551:                        MH_ALIGN(n, 0);
                    552:                        n->m_next = m_split(m, len, wait);
                    553:                        if (n->m_next == 0) {
                    554:                                (void) m_free(n);
                    555:                                return (0);
                    556:                        } else
                    557:                                return (n);
                    558:                } else
                    559:                        MH_ALIGN(n, remain);
                    560:        } else if (remain == 0) {
                    561:                n = m->m_next;
                    562:                m->m_next = 0;
                    563:                return (n);
                    564:        } else {
                    565:                MGET(n, wait, m->m_type);
                    566:                if (n == 0)
                    567:                        return (0);
                    568:                M_ALIGN(n, remain);
                    569:        }
                    570: extpacket:
                    571:        if (m->m_flags & M_EXT) {
                    572:                n->m_flags |= M_EXT;
                    573:                n->m_ext = m->m_ext;
                    574:                mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
                    575:                m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
                    576:                n->m_data = m->m_data + len;
                    577:        } else {
                    578:                bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
                    579:        }
                    580:        n->m_len = remain;
                    581:        m->m_len = len;
                    582:        n->m_next = m->m_next;
                    583:        m->m_next = 0;
                    584:        return (n);
                    585: }
                    586: /*
                    587:  * Routine to copy from device local memory into mbufs.
                    588:  */
                    589: struct mbuf *
                    590: m_devget(buf, totlen, off0, ifp, copy)
                    591:        char *buf;
                    592:        int totlen, off0;
                    593:        struct ifnet *ifp;
                    594:        void (*copy)();
                    595: {
                    596:        register struct mbuf *m;
                    597:        struct mbuf *top = 0, **mp = &top;
                    598:        register int off = off0, len;
                    599:        register char *cp;
                    600:        char *epkt;
                    601:
                    602:        cp = buf;
                    603:        epkt = cp + totlen;
                    604:        if (off) {
1.13    ! cgd       605:                /*
        !           606:                 * If 'off' is non-zero, packet is trailer-encapsulated,
        !           607:                 * so we have to skip the type and length fields.
        !           608:                 */
        !           609:                cp += off + 2 * sizeof(u_int16_t);
        !           610:                totlen -= 2 * sizeof(u_int16_t);
1.9       mycroft   611:        }
                    612:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    613:        if (m == 0)
                    614:                return (0);
                    615:        m->m_pkthdr.rcvif = ifp;
                    616:        m->m_pkthdr.len = totlen;
                    617:        m->m_len = MHLEN;
                    618:
                    619:        while (totlen > 0) {
                    620:                if (top) {
                    621:                        MGET(m, M_DONTWAIT, MT_DATA);
                    622:                        if (m == 0) {
                    623:                                m_freem(top);
                    624:                                return (0);
                    625:                        }
                    626:                        m->m_len = MLEN;
                    627:                }
                    628:                len = min(totlen, epkt - cp);
                    629:                if (len >= MINCLSIZE) {
                    630:                        MCLGET(m, M_DONTWAIT);
                    631:                        if (m->m_flags & M_EXT)
                    632:                                m->m_len = len = min(len, MCLBYTES);
                    633:                        else
                    634:                                len = m->m_len;
                    635:                } else {
                    636:                        /*
                    637:                         * Place initial small packet/header at end of mbuf.
                    638:                         */
                    639:                        if (len < m->m_len) {
                    640:                                if (top == 0 && len + max_linkhdr <= m->m_len)
                    641:                                        m->m_data += max_linkhdr;
                    642:                                m->m_len = len;
                    643:                        } else
                    644:                                len = m->m_len;
                    645:                }
                    646:                if (copy)
                    647:                        copy(cp, mtod(m, caddr_t), (unsigned)len);
                    648:                else
                    649:                        bcopy(cp, mtod(m, caddr_t), (unsigned)len);
                    650:                cp += len;
                    651:                *mp = m;
                    652:                mp = &m->m_next;
                    653:                totlen -= len;
                    654:                if (cp == epkt)
                    655:                        cp = buf;
                    656:        }
                    657:        return (top);
1.1       cgd       658: }

CVSweb <webmaster@jp.NetBSD.org>