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

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: 
1.1.1.3   root       20: #define MBUF_THRESH 30
                     21: 
                     22: /*
                     23:  * Find a nice value for msize
                     24:  * XXX if_maxlinkhdr already in mtu
                     25:  */
1.1.1.7   root       26: #define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + offsetof(struct mbuf, m_dat) + 6)
1.1       root       27: 
                     28: void
1.1.1.5   root       29: m_init(Slirp *slirp)
1.1       root       30: {
1.1.1.5   root       31:     slirp->m_freelist.m_next = slirp->m_freelist.m_prev = &slirp->m_freelist;
                     32:     slirp->m_usedlist.m_next = slirp->m_usedlist.m_prev = &slirp->m_usedlist;
1.1       root       33: }
                     34: 
                     35: /*
                     36:  * Get an mbuf from the free list, if there are none
                     37:  * malloc one
1.1.1.3   root       38:  *
1.1       root       39:  * Because fragmentation can occur if we alloc new mbufs and
                     40:  * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
                     41:  * which tells m_free to actually free() it
                     42:  */
                     43: struct mbuf *
1.1.1.5   root       44: m_get(Slirp *slirp)
1.1       root       45: {
                     46:        register struct mbuf *m;
                     47:        int flags = 0;
1.1.1.3   root       48: 
1.1       root       49:        DEBUG_CALL("m_get");
1.1.1.3   root       50: 
1.1.1.5   root       51:        if (slirp->m_freelist.m_next == &slirp->m_freelist) {
1.1.1.4   root       52:                m = (struct mbuf *)malloc(SLIRP_MSIZE);
1.1       root       53:                if (m == NULL) goto end_error;
1.1.1.5   root       54:                slirp->mbuf_alloced++;
                     55:                if (slirp->mbuf_alloced > MBUF_THRESH)
1.1       root       56:                        flags = M_DOFREE;
1.1.1.5   root       57:                m->slirp = slirp;
1.1       root       58:        } else {
1.1.1.5   root       59:                m = slirp->m_freelist.m_next;
1.1       root       60:                remque(m);
                     61:        }
1.1.1.3   root       62: 
1.1       root       63:        /* Insert it in the used list */
1.1.1.5   root       64:        insque(m,&slirp->m_usedlist);
1.1       root       65:        m->m_flags = (flags | M_USEDLIST);
1.1.1.3   root       66: 
1.1       root       67:        /* Initialise it */
1.1.1.7   root       68:        m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
1.1       root       69:        m->m_data = m->m_dat;
                     70:        m->m_len = 0;
1.1.1.5   root       71:         m->m_nextpkt = NULL;
                     72:         m->m_prevpkt = NULL;
1.1.1.8 ! root       73:         m->arp_requested = false;
        !            74:         m->expiration_date = (uint64_t)-1;
1.1       root       75: end_error:
                     76:        DEBUG_ARG("m = %lx", (long )m);
                     77:        return m;
                     78: }
                     79: 
                     80: void
1.1.1.5   root       81: m_free(struct mbuf *m)
1.1       root       82: {
1.1.1.3   root       83: 
1.1       root       84:   DEBUG_CALL("m_free");
                     85:   DEBUG_ARG("m = %lx", (long )m);
1.1.1.3   root       86: 
1.1       root       87:   if(m) {
                     88:        /* Remove from m_usedlist */
                     89:        if (m->m_flags & M_USEDLIST)
                     90:           remque(m);
1.1.1.3   root       91: 
1.1       root       92:        /* If it's M_EXT, free() it */
                     93:        if (m->m_flags & M_EXT)
                     94:           free(m->m_ext);
                     95: 
                     96:        /*
                     97:         * Either free() it or put it on the free list
                     98:         */
                     99:        if (m->m_flags & M_DOFREE) {
1.1.1.5   root      100:                m->slirp->mbuf_alloced--;
1.1.1.6   root      101:                free(m);
1.1       root      102:        } else if ((m->m_flags & M_FREELIST) == 0) {
1.1.1.5   root      103:                insque(m,&m->slirp->m_freelist);
1.1       root      104:                m->m_flags = M_FREELIST; /* Clobber other flags */
                    105:        }
                    106:   } /* if(m) */
                    107: }
                    108: 
                    109: /*
                    110:  * Copy data from one mbuf to the end of
                    111:  * the other.. if result is too big for one mbuf, malloc()
                    112:  * an M_EXT data segment
                    113:  */
                    114: void
1.1.1.5   root      115: m_cat(struct mbuf *m, struct mbuf *n)
1.1       root      116: {
                    117:        /*
                    118:         * If there's no room, realloc
                    119:         */
                    120:        if (M_FREEROOM(m) < n->m_len)
                    121:                m_inc(m,m->m_size+MINCSIZE);
1.1.1.3   root      122: 
1.1       root      123:        memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
                    124:        m->m_len += n->m_len;
                    125: 
                    126:        m_free(n);
                    127: }
                    128: 
                    129: 
                    130: /* make m size bytes large */
                    131: void
1.1.1.5   root      132: m_inc(struct mbuf *m, int size)
1.1       root      133: {
1.1.1.2   root      134:        int datasize;
                    135: 
1.1       root      136:        /* some compiles throw up on gotos.  This one we can fake. */
                    137:         if(m->m_size>size) return;
                    138: 
                    139:         if (m->m_flags & M_EXT) {
1.1.1.2   root      140:          datasize = m->m_data - m->m_ext;
1.1       root      141:          m->m_ext = (char *)realloc(m->m_ext,size);
1.1.1.2   root      142:          m->m_data = m->m_ext + datasize;
1.1       root      143:         } else {
                    144:          char *dat;
                    145:          datasize = m->m_data - m->m_dat;
                    146:          dat = (char *)malloc(size);
                    147:          memcpy(dat, m->m_dat, m->m_size);
1.1.1.3   root      148: 
1.1       root      149:          m->m_ext = dat;
                    150:          m->m_data = m->m_ext + datasize;
                    151:          m->m_flags |= M_EXT;
                    152:         }
1.1.1.3   root      153: 
1.1       root      154:         m->m_size = size;
                    155: 
                    156: }
                    157: 
                    158: 
                    159: 
                    160: void
1.1.1.5   root      161: m_adj(struct mbuf *m, int len)
1.1       root      162: {
                    163:        if (m == NULL)
                    164:                return;
                    165:        if (len >= 0) {
                    166:                /* Trim from head */
                    167:                m->m_data += len;
                    168:                m->m_len -= len;
                    169:        } else {
                    170:                /* Trim from tail */
                    171:                len = -len;
                    172:                m->m_len -= len;
                    173:        }
                    174: }
                    175: 
                    176: 
                    177: /*
                    178:  * Copy len bytes from m, starting off bytes into n
                    179:  */
                    180: int
1.1.1.5   root      181: m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
1.1       root      182: {
                    183:        if (len > M_FREEROOM(n))
                    184:                return -1;
                    185: 
                    186:        memcpy((n->m_data + n->m_len), (m->m_data + off), len);
                    187:        n->m_len += len;
                    188:        return 0;
                    189: }
                    190: 
                    191: 
                    192: /*
                    193:  * Given a pointer into an mbuf, return the mbuf
                    194:  * XXX This is a kludge, I should eliminate the need for it
                    195:  * Fortunately, it's not used often
                    196:  */
                    197: struct mbuf *
1.1.1.5   root      198: dtom(Slirp *slirp, void *dat)
1.1       root      199: {
                    200:        struct mbuf *m;
1.1.1.3   root      201: 
1.1       root      202:        DEBUG_CALL("dtom");
                    203:        DEBUG_ARG("dat = %lx", (long )dat);
                    204: 
                    205:        /* bug corrected for M_EXT buffers */
1.1.1.5   root      206:        for (m = slirp->m_usedlist.m_next; m != &slirp->m_usedlist;
                    207:             m = m->m_next) {
1.1       root      208:          if (m->m_flags & M_EXT) {
                    209:            if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
                    210:              return m;
                    211:          } else {
                    212:            if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
                    213:              return m;
                    214:          }
                    215:        }
1.1.1.3   root      216: 
1.1       root      217:        DEBUG_ERROR((dfd, "dtom failed"));
1.1.1.3   root      218: 
1.1       root      219:        return (struct mbuf *)0;
                    220: }

unix.superglobalmegacorp.com

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