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 2011-2021 Tintri by DDN, 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 * How much prepend space to put in the first mbuf of a chain. 95 * In SMB we only prepend a 4-byte NBT header, but let's keep the 96 * data part aligned the same as M_ALIGN() does below (8-byte) 97 */ 98 #define MH_PREPEND_SPACE 8 99 100 /* 101 * Macros for type conversion 102 * mtod(m,t) - convert mbuf pointer to data pointer of correct type 103 */ 104 #define mtod(m, t) ((t)((m)->m_data)) 105 106 struct mbuf; 107 typedef void m_ext_free_t(struct mbuf *); 108 109 /* header at beginning of each mbuf: */ 110 struct m_hdr { 111 struct mbuf *mh_next; /* next buffer in chain */ 112 struct mbuf *mh_nextpkt; /* next chain in queue/record */ 113 int mh_len; /* amount of data in this mbuf */ 114 caddr_t mh_data; /* location of data */ 115 short mh_type; /* type of data in this mbuf */ 116 short mh_flags; /* flags; see below */ 117 }; 118 119 /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */ 120 struct pkthdr { 121 int len; /* total packet length */ 122 }; 123 124 125 /* description of external storage mapped into mbuf, valid if M_EXT set */ 126 struct m_ext { 127 caddr_t ext_buf; /* start of external buffer */ 128 uint_t ext_size; /* size of external buffer */ 129 m_ext_free_t *ext_free; /* free function */ 130 void *ext_arg1; /* free func arg */ 131 }; 132 133 typedef struct mbuf { 134 struct m_hdr m_hdr; 135 union { 136 struct { 137 struct pkthdr MH_pkthdr; /* M_PKTHDR set */ 138 union { 139 struct m_ext MH_ext; /* M_EXT set */ 140 char MH_databuf[MHLEN]; 141 } MH_dat; 142 } MH; 143 char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */ 144 } M_dat; 145 } mbuf_t; 146 147 #define m_next m_hdr.mh_next 148 #define m_len m_hdr.mh_len 149 #define m_data m_hdr.mh_data 150 #define m_type m_hdr.mh_type 151 #define m_flags m_hdr.mh_flags 152 #define m_nextpkt m_hdr.mh_nextpkt 153 #define m_act m_nextpkt 154 #define m_pkthdr M_dat.MH.MH_pkthdr 155 #define m_ext M_dat.MH.MH_dat.MH_ext 156 #define m_pktdat M_dat.MH.MH_dat.MH_databuf 157 #define m_dat M_dat.M_databuf 158 159 /* mbuf flags */ 160 #define M_EXT 0x0001 /* has associated external storage */ 161 #define M_PKTHDR 0x0002 /* start of record */ 162 #define M_EOR 0x0004 /* end of record */ 163 164 /* mbuf pkthdr flags, also in m_flags */ 165 #define M_BCAST 0x0100 /* send/received as link-level broadcast */ 166 #define M_MCAST 0x0200 /* send/received as link-level multicast */ 167 168 /* flags copied when copying m_pkthdr */ 169 #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST) 170 171 /* XXX probably only need MT_DATA */ 172 173 /* mbuf types */ 174 #define MT_FREE 0 /* should be on free list */ 175 #define MT_DATA 1 /* dynamic (data) allocation */ 176 #define MT_HEADER 2 /* packet header */ 177 #define MT_SOCKET 3 /* socket structure */ 178 #define MT_PCB 4 /* protocol control block */ 179 #define MT_RTABLE 5 /* routing tables */ 180 #define MT_HTABLE 6 /* IMP host tables */ 181 #define MT_ATABLE 7 /* address resolution tables */ 182 #define MT_SONAME 8 /* socket name */ 183 #define MT_SOOPTS 10 /* socket options */ 184 #define MT_FTABLE 11 /* fragment reassembly header */ 185 #define MT_RIGHTS 12 /* access rights */ 186 #define MT_IFADDR 13 /* interface address */ 187 #define MT_CONTROL 14 /* extra-data protocol message */ 188 #define MT_OOBDATA 15 /* expedited data */ 189 190 /* 191 * flags to malloc: PBSHORTCUT 192 */ 193 #define M_WAITOK 0x0000 194 #define M_NOWAIT 0x0001 195 196 /* flags to m_get/MGET */ 197 #define M_DONTWAIT M_NOWAIT 198 #define M_WAIT M_WAITOK 199 200 /* BEGIN CSTYLED */ 201 202 /* 203 * mbuf allocation/deallocation macros: 204 * 205 * MGET(struct mbuf *m, int how, int type) 206 * allocates an mbuf and initializes it to contain internal data. 207 * 208 * MGETHDR(struct mbuf *m, int how, int type) 209 * allocates an mbuf and initializes it to contain a packet header 210 * and internal data. 211 */ 212 213 #define MGET(m, how, type) { \ 214 m = smb_mbuf_alloc(); \ 215 (m)->m_next = (struct mbuf *)NULL; \ 216 (m)->m_nextpkt = (struct mbuf *)NULL; \ 217 (m)->m_data = (m)->m_dat; \ 218 (m)->m_flags = 0; \ 219 (m)->m_type = (short)(type); \ 220 } 221 222 #define MGETHDR(m, how, type) { \ 223 m = smb_mbuf_alloc(); \ 224 (m)->m_type = (MT_HEADER); \ 225 (m)->m_next = (struct mbuf *)NULL; \ 226 (m)->m_nextpkt = (struct mbuf *)NULL; \ 227 (m)->m_data = (m)->m_pktdat; \ 228 (m)->m_flags = M_PKTHDR; \ 229 } 230 231 #define MCLGET(m, how) \ 232 { \ 233 (m)->m_ext.ext_buf = smb_mbufcl_alloc(); \ 234 (m)->m_data = (m)->m_ext.ext_buf; \ 235 (m)->m_flags |= M_EXT; \ 236 (m)->m_ext.ext_size = MCLBYTES; \ 237 (m)->m_ext.ext_free = smb_mbufcl_free; \ 238 } 239 240 /* 241 * MFREE(struct mbuf *m, struct mbuf *nn) 242 * Free a single mbuf and associated external storage. 243 * Place the successor, if any, in nn. 244 */ 245 #define MFREE(m, nn) \ 246 { \ 247 if ((m)->m_flags & M_EXT) { \ 248 (m)->m_ext.ext_free(m); \ 249 (m)->m_ext.ext_buf = NULL; \ 250 } \ 251 (nn) = (m)->m_next; \ 252 (m)->m_next = 0; \ 253 smb_mbuf_free(m); \ 254 } 255 256 /* 257 * Set the m_data pointer of a newly allocated mbuf to place an object of the 258 * specified size at the end of the mbuf, longword aligned. 259 */ 260 #define M_ALIGN(m, len) \ 261 { (m)->m_data += (MLEN - (len)) &~ (sizeof (int64_t) - 1); } 262 263 /* 264 * As above, for mbufs allocated with m_gethdr/MGETHDR 265 * or initialized by M_COPY_PKTHDR. 266 */ 267 #define MH_ALIGN(m, len) \ 268 { (m)->m_data += (MHLEN - (len)) &~ (sizeof (int64_t) - 1); } 269 270 /* 271 * Return the address of the start of the buffer associated with an mbuf, 272 * handling external storage, packet-header mbufs, and regular data mbufs. 273 * BSD calls this M_START but that conflicts with stream.h (sigh) 274 */ 275 #define MB_START(m) \ 276 (((m)->m_flags & M_EXT) ? (m)->m_ext.ext_buf : \ 277 ((m)->m_flags & M_PKTHDR) ? &(m)->m_pktdat[0] : \ 278 &(m)->m_dat[0]) 279 280 /* 281 * Return the size of the buffer associated with an mbuf, handling external 282 * storage, packet-header mbufs, and regular data mbufs. 283 */ 284 #define M_SIZE(m) \ 285 (((m)->m_flags & M_EXT) ? (m)->m_ext.ext_size : \ 286 ((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN) 287 288 /* 289 * Compute the amount of space available before the current start of data in 290 * an mbuf. 291 */ 292 #define M_LEADINGSPACE(m) ((m)->m_data - MB_START(m)) 293 294 /* 295 * Compute the amount of space available after the end of data in an mbuf. 296 */ 297 #define M_TRAILINGSPACE(m) \ 298 ((MB_START(m) + M_SIZE(m)) - ((m)->m_data + (m)->m_len)) 299 300 /* END CSTYLED */ 301 302 #define SMB_MBC_MAGIC 0x4D42435F 303 #define SMB_MBC_VALID(p) ASSERT((p)->mbc_magic == SMB_MBC_MAGIC) 304 305 typedef struct mbuf_chain { 306 uint32_t mbc_magic; 307 volatile uint32_t flags; /* Various flags */ 308 struct mbuf_chain *shadow_of; /* I'm shadowing someone */ 309 mbuf_t *chain; /* Start of chain */ 310 int32_t max_bytes; /* max # of bytes for chain */ 311 int32_t chain_offset; /* Current offset into chain */ 312 } mbuf_chain_t; 313 314 mbuf_t *smb_mbuf_alloc_ext(caddr_t, int, m_ext_free_t, void *); 315 316 mbuf_t *smb_mbuf_alloc(void); 317 void smb_mbuf_free(mbuf_t *); 318 319 void *smb_mbufcl_alloc(void); 320 void smb_mbufcl_free(mbuf_t *); 321 322 mbuf_t *m_prepend(struct mbuf *m, int plen, int how); 323 void m_adjust(mbuf_t *, int); 324 mbuf_t *m_free(mbuf_t *); 325 void m_freem(mbuf_t *); 326 void smb_mbc_init(void); 327 void smb_mbc_fini(void); 328 mbuf_chain_t *smb_mbc_alloc(uint32_t); 329 void smb_mbc_free(mbuf_chain_t *); 330 331 #ifdef __cplusplus 332 } 333 #endif 334 335 #endif /* _SMBSRV_MBUF_H */ 336