Annotation of qemu/slirp/mbuf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1995 Danny Gasparovski
        !             3:  *
        !             4:  * Please read the file COPYRIGHT for the
        !             5:  * terms and conditions of the copyright.
        !             6:  */
        !             7: 
        !             8: /*
        !             9:  * mbuf's in SLiRP are much simpler than the real mbufs in
        !            10:  * FreeBSD.  They are fixed size, determined by the MTU,
        !            11:  * so that one whole packet can fit.  Mbuf's cannot be
        !            12:  * chained together.  If there's more data than the mbuf
        !            13:  * could hold, an external malloced buffer is pointed to
        !            14:  * by m_ext (and the data pointers) and M_EXT is set in
        !            15:  * the flags
        !            16:  */
        !            17: 
        !            18: #include <slirp.h>
        !            19: 
        !            20: struct mbuf *mbutl;
        !            21: char   *mclrefcnt;
        !            22: int mbuf_alloced = 0;
        !            23: struct mbuf m_freelist, m_usedlist;
        !            24: int mbuf_thresh = 30;
        !            25: int mbuf_max = 0;
        !            26: int msize;
        !            27: 
        !            28: void
        !            29: m_init()
        !            30: {
        !            31:        m_freelist.m_next = m_freelist.m_prev = &m_freelist;
        !            32:        m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
        !            33:        msize_init();
        !            34: }
        !            35: 
        !            36: void
        !            37: msize_init()
        !            38: {
        !            39:        /*
        !            40:         * Find a nice value for msize
        !            41:         * XXX if_maxlinkhdr already in mtu
        !            42:         */
        !            43:        msize = (if_mtu>if_mru?if_mtu:if_mru) + 
        !            44:                        if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
        !            45: }
        !            46: 
        !            47: /*
        !            48:  * Get an mbuf from the free list, if there are none
        !            49:  * malloc one
        !            50:  * 
        !            51:  * Because fragmentation can occur if we alloc new mbufs and
        !            52:  * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
        !            53:  * which tells m_free to actually free() it
        !            54:  */
        !            55: struct mbuf *
        !            56: m_get()
        !            57: {
        !            58:        register struct mbuf *m;
        !            59:        int flags = 0;
        !            60:        
        !            61:        DEBUG_CALL("m_get");
        !            62:        
        !            63:        if (m_freelist.m_next == &m_freelist) {
        !            64:                m = (struct mbuf *)malloc(msize);
        !            65:                if (m == NULL) goto end_error;
        !            66:                mbuf_alloced++;
        !            67:                if (mbuf_alloced > mbuf_thresh)
        !            68:                        flags = M_DOFREE;
        !            69:                if (mbuf_alloced > mbuf_max)
        !            70:                        mbuf_max = mbuf_alloced;
        !            71:        } else {
        !            72:                m = m_freelist.m_next;
        !            73:                remque(m);
        !            74:        }
        !            75:        
        !            76:        /* Insert it in the used list */
        !            77:        insque(m,&m_usedlist);
        !            78:        m->m_flags = (flags | M_USEDLIST);
        !            79:        
        !            80:        /* Initialise it */
        !            81:        m->m_size = msize - sizeof(struct m_hdr);
        !            82:        m->m_data = m->m_dat;
        !            83:        m->m_len = 0;
        !            84:        m->m_nextpkt = 0;
        !            85:        m->m_prevpkt = 0;
        !            86: end_error:
        !            87:        DEBUG_ARG("m = %lx", (long )m);
        !            88:        return m;
        !            89: }
        !            90: 
        !            91: void
        !            92: m_free(m)
        !            93:        struct mbuf *m;
        !            94: {
        !            95:        
        !            96:   DEBUG_CALL("m_free");
        !            97:   DEBUG_ARG("m = %lx", (long )m);
        !            98:        
        !            99:   if(m) {
        !           100:        /* Remove from m_usedlist */
        !           101:        if (m->m_flags & M_USEDLIST)
        !           102:           remque(m);
        !           103:        
        !           104:        /* If it's M_EXT, free() it */
        !           105:        if (m->m_flags & M_EXT)
        !           106:           free(m->m_ext);
        !           107: 
        !           108:        /*
        !           109:         * Either free() it or put it on the free list
        !           110:         */
        !           111:        if (m->m_flags & M_DOFREE) {
        !           112:                free(m);
        !           113:                mbuf_alloced--;
        !           114:        } else if ((m->m_flags & M_FREELIST) == 0) {
        !           115:                insque(m,&m_freelist);
        !           116:                m->m_flags = M_FREELIST; /* Clobber other flags */
        !           117:        }
        !           118:   } /* if(m) */
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * Copy data from one mbuf to the end of
        !           123:  * the other.. if result is too big for one mbuf, malloc()
        !           124:  * an M_EXT data segment
        !           125:  */
        !           126: void
        !           127: m_cat(m, n)
        !           128:        register struct mbuf *m, *n;
        !           129: {
        !           130:        /*
        !           131:         * If there's no room, realloc
        !           132:         */
        !           133:        if (M_FREEROOM(m) < n->m_len)
        !           134:                m_inc(m,m->m_size+MINCSIZE);
        !           135:        
        !           136:        memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
        !           137:        m->m_len += n->m_len;
        !           138: 
        !           139:        m_free(n);
        !           140: }
        !           141: 
        !           142: 
        !           143: /* make m size bytes large */
        !           144: void
        !           145: m_inc(m, size)
        !           146:         struct mbuf *m;
        !           147:         int size;
        !           148: {
        !           149:        /* some compiles throw up on gotos.  This one we can fake. */
        !           150:         if(m->m_size>size) return;
        !           151: 
        !           152:         if (m->m_flags & M_EXT) {
        !           153:          /* datasize = m->m_data - m->m_ext; */
        !           154:          m->m_ext = (char *)realloc(m->m_ext,size);
        !           155: /*             if (m->m_ext == NULL)
        !           156:  *                     return (struct mbuf *)NULL;
        !           157:  */            
        !           158:          /* m->m_data = m->m_ext + datasize; */
        !           159:         } else {
        !           160:          int datasize;
        !           161:          char *dat;
        !           162:          datasize = m->m_data - m->m_dat;
        !           163:          dat = (char *)malloc(size);
        !           164: /*             if (dat == NULL)
        !           165:  *                     return (struct mbuf *)NULL;
        !           166:  */
        !           167:          memcpy(dat, m->m_dat, m->m_size);
        !           168:          
        !           169:          m->m_ext = dat;
        !           170:          m->m_data = m->m_ext + datasize;
        !           171:          m->m_flags |= M_EXT;
        !           172:         }
        !           173:  
        !           174:         m->m_size = size;
        !           175: 
        !           176: }
        !           177: 
        !           178: 
        !           179: 
        !           180: void
        !           181: m_adj(m, len)
        !           182:        struct mbuf *m;
        !           183:        int len;
        !           184: {
        !           185:        if (m == NULL)
        !           186:                return;
        !           187:        if (len >= 0) {
        !           188:                /* Trim from head */
        !           189:                m->m_data += len;
        !           190:                m->m_len -= len;
        !           191:        } else {
        !           192:                /* Trim from tail */
        !           193:                len = -len;
        !           194:                m->m_len -= len;
        !           195:        }
        !           196: }
        !           197: 
        !           198: 
        !           199: /*
        !           200:  * Copy len bytes from m, starting off bytes into n
        !           201:  */
        !           202: int
        !           203: m_copy(n, m, off, len)
        !           204:        struct mbuf *n, *m;
        !           205:        int off, len;
        !           206: {
        !           207:        if (len > M_FREEROOM(n))
        !           208:                return -1;
        !           209: 
        !           210:        memcpy((n->m_data + n->m_len), (m->m_data + off), len);
        !           211:        n->m_len += len;
        !           212:        return 0;
        !           213: }
        !           214: 
        !           215: 
        !           216: /*
        !           217:  * Given a pointer into an mbuf, return the mbuf
        !           218:  * XXX This is a kludge, I should eliminate the need for it
        !           219:  * Fortunately, it's not used often
        !           220:  */
        !           221: struct mbuf *
        !           222: dtom(dat)
        !           223:        void *dat;
        !           224: {
        !           225:        struct mbuf *m;
        !           226:        
        !           227:        DEBUG_CALL("dtom");
        !           228:        DEBUG_ARG("dat = %lx", (long )dat);
        !           229: 
        !           230:        /* bug corrected for M_EXT buffers */
        !           231:        for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
        !           232:          if (m->m_flags & M_EXT) {
        !           233:            if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
        !           234:              return m;
        !           235:          } else {
        !           236:            if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
        !           237:              return m;
        !           238:          }
        !           239:        }
        !           240:        
        !           241:        DEBUG_ERROR((dfd, "dtom failed"));
        !           242:        
        !           243:        return (struct mbuf *)0;
        !           244: }
        !           245: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.