1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
  28  * All rights reserved.
  29  *
  30  * Redistribution and use in source and binary forms, with or without
  31  * modification, are permitted provided that the following conditions
  32  * are met:
  33  * 1. Redistributions of source code must retain the above copyright
  34  *    notice, this list of conditions and the following disclaimer.
  35  * 2. Redistributions in binary form must reproduce the above copyright
  36  *    notice, this list of conditions and the following disclaimer in the
  37  *    documentation and/or other materials provided with the distribution.
  38  * 3. All advertising materials mentioning features or use of this software
  39  *    must display the following acknowledgement:
  40  *      This product includes software developed by the University of
  41  *      California, Berkeley and its contributors.
  42  * 4. Neither the name of the University nor the names of its contributors
  43  *    may be used to endorse or promote products derived from this software
  44  *    without specific prior written permission.
  45  *
  46  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  49  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  50  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  56  * SUCH DAMAGE.
  57  *
  58  */
  59 
  60 #ifndef _SMBSRV_MBUF_H
  61 #define _SMBSRV_MBUF_H
  62 
  63 /*
  64  * This mbuf simulation should be replaced with (native) mblk_t support.
  65  */
  66 
  67 #include <sys/types.h>
  68 #include <sys/param.h>
  69 #include <sys/kmem.h>
  70 #include <smbsrv/string.h>
  71 
  72 #ifdef __cplusplus
  73 extern "C" {
  74 #endif
  75 
  76 #define MSIZE           256
  77 #define MCLBYTES        8192
  78 
  79 /*
  80  * Mbufs are of a single size, MSIZE (machine/machparam.h), which
  81  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
  82  * MCLBYTES (also in machine/machparam.h), which has no additional overhead
  83  * and is used instead of the internal data area; this is done when
  84  * at least MINCLSIZE of data must be stored.
  85  */
  86 
  87 #define MLEN            (MSIZE - sizeof (struct m_hdr)) /* normal data len */
  88 #define MHLEN           (MLEN - sizeof (struct pkthdr)) /* data len w/pkthdr */
  89 
  90 #define MINCLSIZE       (MHLEN + MLEN)  /* smallest amount to put in cluster */
  91 
  92 /*
  93  * Macros for type conversion
  94  * mtod(m,t) -  convert mbuf pointer to data pointer of correct type
  95  */
  96 #define mtod(m, t)      ((t)((m)->m_data))
  97 
  98 
  99 /* header at beginning of each mbuf: */
 100 struct m_hdr {
 101         struct  mbuf *mh_next;          /* next buffer in chain */
 102         struct  mbuf *mh_nextpkt;       /* next chain in queue/record */
 103         int     mh_len;                 /* amount of data in this mbuf */
 104         caddr_t mh_data;                /* location of data */
 105         short   mh_type;                /* type of data in this mbuf */
 106         short   mh_flags;               /* flags; see below */
 107 };
 108 
 109 /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
 110 struct  pkthdr {
 111         int     len;            /* total packet length */
 112 };
 113 
 114 
 115 /* description of external storage mapped into mbuf, valid if M_EXT set */
 116 struct m_ext {
 117         caddr_t ext_buf;                /* start of buffer */
 118         int     (*ext_ref)();           /* refcount adjust function */
 119         uint_t  ext_size;               /* size of buffer, for ext_free */
 120 };
 121 
 122 typedef struct mbuf {
 123         struct  m_hdr m_hdr;
 124         union {
 125                 struct {
 126                         struct  pkthdr MH_pkthdr;       /* M_PKTHDR set */
 127                         union {
 128                                 struct  m_ext MH_ext;   /* M_EXT set */
 129                                 char    MH_databuf[MHLEN];
 130                         } MH_dat;
 131                 } MH;
 132                 char    M_databuf[MLEN];                /* !M_PKTHDR, !M_EXT */
 133         } M_dat;
 134 } mbuf_t;
 135 
 136 #define m_next          m_hdr.mh_next
 137 #define m_len           m_hdr.mh_len
 138 #define m_data          m_hdr.mh_data
 139 #define m_type          m_hdr.mh_type
 140 #define m_flags         m_hdr.mh_flags
 141 #define m_nextpkt       m_hdr.mh_nextpkt
 142 #define m_act           m_nextpkt
 143 #define m_pkthdr        M_dat.MH.MH_pkthdr
 144 #define m_ext           M_dat.MH.MH_dat.MH_ext
 145 #define m_pktdat        M_dat.MH.MH_dat.MH_databuf
 146 #define m_dat           M_dat.M_databuf
 147 
 148 /* mbuf flags */
 149 #define M_EXT           0x0001  /* has associated external storage */
 150 #define M_PKTHDR        0x0002  /* start of record */
 151 #define M_EOR           0x0004  /* end of record */
 152 
 153 /* mbuf pkthdr flags, also in m_flags */
 154 #define M_BCAST         0x0100  /* send/received as link-level broadcast */
 155 #define M_MCAST         0x0200  /* send/received as link-level multicast */
 156 
 157 /* flags copied when copying m_pkthdr */
 158 #define M_COPYFLAGS     (M_PKTHDR|M_EOR|M_BCAST|M_MCAST)
 159 
 160 /* XXX probably only need MT_DATA */
 161 
 162 /* mbuf types */
 163 #define MT_FREE         0       /* should be on free list */
 164 #define MT_DATA         1       /* dynamic (data) allocation */
 165 #define MT_HEADER       2       /* packet header */
 166 #define MT_SOCKET       3       /* socket structure */
 167 #define MT_PCB          4       /* protocol control block */
 168 #define MT_RTABLE       5       /* routing tables */
 169 #define MT_HTABLE       6       /* IMP host tables */
 170 #define MT_ATABLE       7       /* address resolution tables */
 171 #define MT_SONAME       8       /* socket name */
 172 #define MT_SOOPTS       10      /* socket options */
 173 #define MT_FTABLE       11      /* fragment reassembly header */
 174 #define MT_RIGHTS       12      /* access rights */
 175 #define MT_IFADDR       13      /* interface address */
 176 #define MT_CONTROL      14      /* extra-data protocol message */
 177 #define MT_OOBDATA      15      /* expedited data  */
 178 
 179 /*
 180  * flags to malloc: PBSHORTCUT
 181  */
 182 #define M_WAITOK        0x0000
 183 #define M_NOWAIT        0x0001
 184 
 185 /* flags to m_get/MGET */
 186 #define M_DONTWAIT      M_NOWAIT
 187 #define M_WAIT          M_WAITOK
 188 
 189 
 190 /*
 191  * mbuf allocation/deallocation macros:
 192  *
 193  *      MGET(struct mbuf *m, int how, int type)
 194  * allocates an mbuf and initializes it to contain internal data.
 195  *
 196  *      MGETHDR(struct mbuf *m, int how, int type)
 197  * allocates an mbuf and initializes it to contain a packet header
 198  * and internal data.
 199  */
 200 
 201 #define MGET(m, how, type) { \
 202         m = smb_mbuf_alloc(); \
 203         (m)->m_next = (struct mbuf *)NULL; \
 204         (m)->m_nextpkt = (struct mbuf *)NULL; \
 205         (m)->m_data = (m)->m_dat; \
 206         (m)->m_flags = 0; \
 207         (m)->m_type = (short)(type); \
 208 }
 209 
 210 #define MGETHDR(m, how, type) { \
 211         m = smb_mbuf_alloc(); \
 212         (m)->m_type = (MT_HEADER); \
 213         (m)->m_next = (struct mbuf *)NULL; \
 214         (m)->m_nextpkt = (struct mbuf *)NULL; \
 215         (m)->m_data = (m)->m_pktdat; \
 216         (m)->m_flags = M_PKTHDR; \
 217 }
 218 
 219 #define MCLGET(m, how) \
 220         { \
 221                 (m)->m_ext.ext_buf = smb_mbufcl_alloc();     \
 222                 (m)->m_data = (m)->m_ext.ext_buf;         \
 223                 (m)->m_flags |= M_EXT;                               \
 224                 (m)->m_ext.ext_size = MCLBYTES;                      \
 225                 (m)->m_ext.ext_ref = smb_mbufcl_ref;         \
 226         }
 227 
 228 /*
 229  * MFREE(struct mbuf *m, struct mbuf *nn)
 230  * Free a single mbuf and associated external storage.
 231  * Place the successor, if any, in nn.
 232  */
 233 #define MFREE(m, nn) \
 234         { \
 235                 if ((m)->m_flags & M_EXT) {                  \
 236                         (*((m)->m_ext.ext_ref))((m)->m_ext.ext_buf,       \
 237                             (m)->m_ext.ext_size, -1);                        \
 238                         (m)->m_ext.ext_buf = 0;                              \
 239                 }                                                       \
 240                 (nn) = (m)->m_next;                                  \
 241                 (m)->m_next = 0;                                     \
 242                 smb_mbuf_free(m);                                       \
 243         }
 244 
 245 
 246 
 247 /*
 248  * As above, for mbufs allocated with m_gethdr/MGETHDR
 249  * or initialized by M_COPY_PKTHDR.
 250  */
 251 #define MH_ALIGN(m, len) \
 252         { (m)->m_data += (MHLEN - (len)) &~ (sizeof (int32_t) - 1); }
 253 
 254 #define SMB_MBC_MAGIC           0x4D42435F
 255 #define SMB_MBC_VALID(p)        ASSERT((p)->mbc_magic == SMB_MBC_MAGIC)
 256 
 257 typedef struct mbuf_chain {
 258         uint32_t                mbc_magic;
 259         volatile uint32_t       flags;          /* Various flags */
 260         struct mbuf_chain       *shadow_of;     /* I'm shadowing someone */
 261         mbuf_t                  *chain;         /* Start of chain */
 262         int32_t                 max_bytes;      /* max # of bytes for chain */
 263         int32_t                 chain_offset;   /* Current offset into chain */
 264 } mbuf_chain_t;
 265 
 266 mbuf_t *smb_mbuf_alloc(void);
 267 void smb_mbuf_free(mbuf_t *);
 268 
 269 void *smb_mbufcl_alloc(void);
 270 void smb_mbufcl_free(void *);
 271 int smb_mbufcl_ref(void *, uint_t, int);
 272 
 273 mbuf_t *m_free(mbuf_t *);
 274 void m_freem(mbuf_t *);
 275 void smb_mbc_init(void);
 276 void smb_mbc_fini(void);
 277 mbuf_chain_t *smb_mbc_alloc(uint32_t);
 278 void smb_mbc_free(mbuf_chain_t *);
 279 
 280 #ifdef __cplusplus
 281 }
 282 #endif
 283 
 284 #endif /* _SMBSRV_MBUF_H */