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 */