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