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