/* @(#)99       1.8  src/bos/kernel/sys/mbuf_base.h, sysuipc, bos72X, x2022_13A4 3/24/22 11:11:24 */

#ifndef	_SYS_MBUF_BASE_H_
#define	_SYS_MBUF_BASE_H_

#ifdef __cplusplus
extern "C" {

struct mbuf;
#endif

#define	MSIZE		512
#define	MCLBYTES	CLBYTES			/* XXX */

#include "sys/xmem.h"
#include "sys/trchkid.h"
#if	defined(_KERNEL) && !defined(_NET_GLOBALS_H_)
#include "net/net_globals.h"
#endif
#ifndef	NET_MALLOC
#include "net/net_malloc.h"
#endif
#include <sys/adspace.h>
#include <sys/ras.h>
#include <net/net_secattr.h>
#include <sys/ras_error.h>
#include <sys/lock_def.h>

/* -------------------------------------------------------------------------------------
// Definitions
*/

#define	MLEN			(MSIZE - sizeof(struct m_hdr))		/* normal data len */
#define	MHLEN			(MLEN - sizeof(struct pkthdr))		/* data len w/pkthdr */
#define MQOSLEN			(MHLEN - sizeof(struct qoshdr) 	\
							- sizeof(struct __m_ext) 	\
							- sizeof(struct suminfo))
#define MSUMLEN			(MHLEN - sizeof(struct suminfo))
#define MDCBFLUSHLEN	(MQOSLEN-sizeof(dcbflushinfo_t))
#define MINCLSIZE		(MHLEN + 3*MLEN) 					/* smallest amount to put in cluster */
#define	M_MAXCOMPRESS	(MHLEN / 2)							/* max amount to copy for compression */

#define	M_COPYALL		1000000000							/* length to m_copy to copy all */
/* XXX:  Is this still okay in a 64-bit world? */

#define	M_DONTWAIT		0									/* do not wait for memory allocations */
#define	M_WAIT			1									/* able to wait for memory allocations */

typedef ulong 			memreg_t;
typedef u_int 			__mh_flags_t;

/* -------------------------------------------------------------------------------------
// External References
*/

#ifdef _KERNEL
extern struct mbstat mbstat;			/* statistics */
extern int	max_linkhdr;				/* largest link-level header */
extern int	max_protohdr;				/* largest protocol header */
extern int	max_hdr;					/* largest link+protocol header */
extern int	max_datalen;				/* MHLEN - max_hdr */
extern int	mclbytes;					/* variable version of MCLBYTES */
#endif
extern struct xmem mclxmemd;

/*
 * Mbufs are of a single size, MSIZE (machine/machparam.h), which
 * includes overhead.  An mbuf may add a single "mbuf cluster" of size
 * MCLBYTES (also in machine/machparam.h), which has no additional overhead
 * and is used instead of the internal data area; this is done when
 * at least MINCLSIZE of data must be stored.
 */

/* =====================================================================================
// NAME: 	m_hdr
// DESC: 	header at beginning of each mbuf
// ==================================================================================== */

#define EYEC_MBUFA      __EYEC8('m','b','u','f','A','L','L','')/* %mbufALL */
#define EYEC_MBUFF      __EYEC8('m','b','u','f','F','R','E','')/* %mbufFRE */

/* flags (m_flags) */
/* 16-bit field in 32-bit kernel, 32-bit field in 64-bit kernel. */

#define	M_EXT				0x0001		/* has associated external storage */
#define	M_PKTHDR			0x0002		/* start of record */
#define	M_EOR				0x0004		/* end of record */
#define	M_MPEG				0x0010		/* hold MPEG video data */
#define M_QOS				0x0020		/* mbuf contains a QoS header */
#define M_EXT2				0x0040		/* mbuf to be freed externally */
#define M_IPV6				0x0080		/* mbuf contains an IPv6 datagram */
/* mbuf pkthdr flags, also in m_flags */
#define	M_BCAST				0x0100		/* send/received as link-level broadcast */
#define	M_MCAST				0x0200		/* send/received as link-level multicast */
#define	M_WCARD				0x0400		/* received as network-level broadcast */
#define	M_MLOOP				0x0800		/* multicast sent/rcvd thru loopback intf */
#define	M_CHECKSUM_TX		0x1000		/* transmitted mbuf contains checksum information */
#define	M_CHECKSUM_RX		0x2000		/* received mbuf contains checksum information */
#define	M_PSEG				0x0008		/* mbuf chain contains private segment */
#define	M_MAPPED			0x4000		/* private segment in buffer is mapped in */
#define	M_LARGESEND			0x8000		/* ethernet largesend */
#define M_DCBFLUSH_LOCAL	0x10000 	/* Set by the device driver, to allow for a flush*/
#define M_LARGESEND_RX		0x20000		/* Receive largesend packet*/
#define	M_TIMESTAMP			0x40000		/* Timestamp is needed for this pkt */
#define	M_TUNNEL	        0x80000		/* Tunnel pkt */

/* expansion flags (m_flags2) */

#define	M_CGA				0x0001			/* prefer CGA for source address */
#define	M_NONCGA			0x0002			/* prefer non-CGA for source address */
#define M_FILTER			0x0004			/* mbuf trace flag on socket, Filtered Tracing */
#define M_SEND				0x0010
#define M_REAL				0x0020
#define M_VIRT				0x0040
#define M_SVM				(M_SEND|M_REAL|M_VIRT)
#define M_LARGESEND_PLATFORM            0x0100                  /* platform largesend */
#define M_IGNORE_BYPASS		0x0200			/* Do not route to bypass protocol */
#define M_USE_MCACHE		0x0400          /* mbuf header cache is being used */	
#define M_USE_IPORESULTS        0x0800          /* ( Defect 1148798 ) use the 'ipout_results' structure */

/* flags copied when copying m_pkthdr */
#define	M_COPYFLAGS			(~(M_EXT|M_EXT2|M_PSEG|M_MAPPED|M_DCBFLUSH_LOCAL))
#define	M_COPYFLAGS2		(~(M_CGA|M_NONCGA|M_FILTER|M_SEND|M_REAL|M_VIRT|M_LARGESEND_PLATFORM|M_IGNORE_BYPASS))

/* types (m_type) */

#define	MT_FREE				0				/* should be on free list */
#define	MT_DATA				1				/* dynamic (data) allocation */
#define	MT_HEADER			2				/* packet header */
#define	MT_SOCKET			3				/* socket structure */
#define	MT_PCB				4				/* protocol control block */
#define	MT_RTABLE			5				/* routing tables */
#define	MT_HTABLE			6				/* IMP host tables */
#define	MT_ATABLE			7				/* address resolution tables */
#define	MT_SONAME			8				/* socket name */
#define	MT_SOOPTS			10				/* socket options */
#define	MT_FTABLE			11				/* fragment reassembly header */
#define	MT_RIGHTS			12				/* access rights */
#define	MT_IFADDR			13				/* interface address */
#define MT_CONTROL			14				/* extra-data protocol message */
#define MT_OOBDATA			15				/* expedited data  */
#ifdef IP_MULTICAST							/* to support IP multicasting */
#define	MT_IPMOPTS			16				/* internet multicast options */
#define	MT_IPMADDR			17				/* internet multicast address */
#define	MT_IFMADDR			18				/* link-level multicast address */
#define	MT_MRTABLE			19				/* multicast routing tables */
#endif
#define MT_IEEE1284     	20  			/* ecp parallel port data  */
#define MT_IPSEC			21				/* buffer holding ipsec data */
#define MT_MAX				32				/* e.g. */

struct m_hdr
{
    struct mbuf *mh_next;					/* next buffer in chain */
    struct mbuf *mh_nextpkt;				/* next chain in queue/record */
    long mh_len;							/* amount of data in this mbuf */
    caddr_t	mh_data;						/* location of data */
    short mh_type;							/* type of data in this mbuf */
    unsigned short mh_cid;					/* corral id */
    __mh_flags_t mh_flags;					/* flags; see below */
    long mh_flags2;							/* expansion to the flags field */
    void *mh_event;							/* pointer to an event tied to pkt */
    eye_catch8b_t mh_eyecat;
    struct net_secattr *mh_mls;				/* MLS security info */
    struct mclContig *mh_contig;			/* contig mpool support struct */
    long mh_options[3];						/* options field for local use */
};

/* =====================================================================================
// NAME: 	pkthdr
// DESC: 	record/packet header in first mbuf of chain; valid if M_PKTHDR set
// 			XXX: We don't use the INRIA union here, since the define for
//      		rcvif (to get through the union) was breaking other folks
// ==================================================================================== */

struct pkthdr
{
    long len;								/* total packet length */
    struct ifnet *rcvif;					/* rcv interface */
};

/* =====================================================================================
// NAME: 	extDebug_t
// DESC: 	ext debug section
// ==================================================================================== */

/* extDebug flags */
#define CLUST_FREE      	0x00000001 		/* Cluster is free */
#define CLUST_ALLOCATED 	0x00000002 		/* Cluster is allocated */
#define CLUST_HIDDEN    	0x00000004 		/* Cluster is hidden */
#define MAX_TRACEBACK 10

typedef struct mpool_debug
{
    caddr_t ext_addr;                    	/* the cluster address              */
    long ext_flags;                      	/* flags listed above               */
    void *ext_traceback[2*MAX_TRACEBACK];	/* the traceback for gets/frees     */

} extDebug_t;

/* =====================================================================================
// NAME: 	__m_ext
// DESC: 	Description of external storage mapped into mbuf
//			valid if M_EXT set
// ==================================================================================== */

struct __m_ext
{
    caddr_t ext_buf;                		/* start of buffer */
#ifdef  _KERNEL
    void (*ext_free)(caddr_t, u_long, caddr_t);
#else
    void (*ext_free)();          			/* free routine if not the usual    */
#endif
    u_long  ext_size;               		/* size of buffer, for ext_free     */
    caddr_t ext_arg;                		/* additional ext_free argument     */
    /* ext_arg is unused by mpool code	*/
    struct  ext_refq						/* reference list */
    {
        struct ext_refq *forw, *back;

    } ext_ref;

    int ext_hasxm;                  		/* cross memory descriptor present? */
    struct xmem ext_xmemd;          		/* cross memory descriptor 			*/
    extDebug_t *ext_debug;		    		/* debug pointer                    */
    struct mclust_pool *ext_mpool;  		/* valid for mpool mbufs 			*/
    uint16_t ext_bktidx;            		/* The bucket index for the mpool  	*/
};

/* =====================================================================================
// NAME: 	qoshdr
// DESC: 	Quality Of Service (QOS) header objects
// ==================================================================================== */

struct qoshdr
{
    void *qos_ifhandle;						/* IFNET reservation identifier 	*/
    u_long qos_priority;					/* R-SPEC service level 			*/
    int	qos_reserved[2];					/* Room to grow... 					*/
};

/* =====================================================================================
// NAME: 	suminfo
// DESC: 	common checksum header objects
// ==================================================================================== */

/* Definition for suminfo flags */

#define IP_SUM_GOOD    1 		/* IP checksum was offloaded by the adapter and
                          	   		was found to be good */

#define PROTO_SUM_GOOD 2 		/* TCP or UDP checksum was offloaded by the adapter
                            		and was found to be good */

#define PROTO_NO_SUM   4 		/* Support for Virtual adapter offload when no TCP checksum 
						    		is present. This flag can be used only with
									PROTO_BY_FLAG set*/

/* Definition for suminfo type */

#define PROTO_BY_VALUE 0 		/* protocol checksum passed by value in headersum */
#define IP_BY_FLAG     1 		/* IP checksum flagged as good/bad */
#define PROTO_BY_FLAG  2		/* TCP/UDP checksum flagged as good/bad */

struct suminfo
{
    u_short type;      						/* RX - type of receive checksum 	*/
    u_short flags;     						/* flags 							*/
    u_short *sump;      					/* TX - where to put protocol sum 	*/
    caddr_t	iphdr;		    				/* TX - ip header address 			*/
    size_t iplen;   	    				/* TX - ip header length		 	*/
    size_t protolen;	    				/* TX - potocol header length		*/
    u_short headersum; 						/* RX - pseudo-header sum 			*/
};

/* =====================================================================================
// NAME: 	dcbflushinfo
// DESC: 	common flush header objects
// ==================================================================================== */

typedef struct dcbflushinfo
{
    uint64_t m;             				/* Saved address of the mbuf     	*/
    uint64_t data;          				/* M_EXT data address to flush   	*/
    uint64_t len;           				/* Amount to flush               	*/

} dcbflushinfo_t;

/* =====================================================================================
// NAME: 	mbuf
// DESC: 	message buffer definition
// ==================================================================================== */

typedef struct mbuf
{
    struct m_hdr m_hdr;
    union
    {
        struct
        {
            /* Only use when M_PKTHDR set */
            struct	pkthdr MH_pkthdr;

            union
            {
                /* Only use when M_EXT set */
                struct  __m_ext MH_ext;

                char MH_databuf[MHLEN];

                /*
                 * MH_qos is used when M_QOS is set or when
                 * both M_EXT and (M_CHECKSUM_RX or
                 * M_CHECKSUM_TX) are set.
                 */
                struct
                {
                    struct __m_ext MH_ext;
                    struct suminfo MH_suminfo;
                    struct qoshdr MH_qoshdr;
                    char MH_qosdatabuf[MQOSLEN];

                } MH_qos;

                /* Only use when M_DCBFLUSH is set */
                struct
                {
                    struct __m_ext MH_ext;
                    struct suminfo MH_suminfo;
                    struct qoshdr MH_qoshdr;
                    struct dcbflushinfo MH_dcbflushinfo;
                    char MH_dcbflushdatabuf[MDCBFLUSHLEN];

                } MH_dcbflush;

                /*
                 * MH_sum is used when (M_CHECKSUM_TX or
                 * M_CHECKSUM_RX) is set but M_EXT is clear.
                 */
                struct
                {
                    struct suminfo MH_suminfo;
                    char MH_sumdat[MSUMLEN];

                } MH_sum;

            } MH_dat;

        } MH;

        char M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */

    } M_dat;

} mbuf_t;

/* =====================================================================================
// NAME: 	mbreq
// DESC: 	mb request definition
// ==================================================================================== */

struct mbreq
{
    int low_mbuf;						/* mbuf low water mark                  */
    int low_clust;						/* mbuf page size low water mark        */
    int initial_mbuf;					/* allocation of mbufs needed           */
    int initial_clust;					/* allocation of page size mbufs needed */
};

/* =====================================================================================
// NAME: 	mbstat
// DESC: 	mbuf statistics
// ==================================================================================== */

struct mbstat
{
    u_long	m_mbufs;					/* mbufs obtained from page pool - UNUSED */
    u_long	m_clusters;					/* clusters obtained from page pool - UNUSED */
    u_long	m_mfree;					/* free mbufs - UNUSED */
    u_long	m_clfree;					/* free clusters - UNUSED */
    u_long	m_drops;					/* times failed to find space */
    u_long	m_wait;						/* times socket not created due to sockthresh */
    u_long	m_drain;					/* times drained protocols for space */
    u_long	m_mtypes[MT_MAX]; 			/* type specific mbuf allocations - UNUSED */
};

void * getcaller(void);

/* =====================================================================================
// NAME: 	mpool_cache
// DESC: 	mbuf header allocation pool objects
// ==================================================================================== */

#define EYEC_MCACHE     __EYEC8('m','c','a','c','h','e','A','')/* %mcacheA */

typedef struct mpool_cache 
{
    eye_catch8b_t           pool_eyecat;
#ifndef _KERNEL
#define simple_lock_data_t  long
#define lock_data_t         struct { int a; int b; }
#endif
    simple_lock_data_t      pool_lock;	
    struct mbuf             *free_list;
    int                     pool_maximum_size;
    int                     pool_current_size;    	
    int                     missed_allocations;	

} mpool_cache_t;

/* (Defect 1148798) */
/* =====================================================================================
// NAME:        ipout_results
// DESC:        ip output results
// ==================================================================================== */

#define IPOUT_ROUTE_CHANGED 0x00000001
#define IPOUT_REROUTE_USED  0x00000002
#define IPOUT_ROUTE_CLEANUP 0x00000004

struct ipout_results
{
    int                 flags;
    struct ifnet        *ifp_used;
    struct rtentry      *new_rt;
};
#ifdef __cplusplus
}
#endif

#endif /* _SYS_MBUF_BASE_H_ */
