Home | History | Annotate | Line # | Download | only in sys
      1 /*	$OpenBSD: haesbaert $	*/
      2 /*	$NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 1982, 1986, 1988, 1993
      6  *	The Regents of the University of California.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. Neither the name of the University nor the names of its contributors
     17  *    may be used to endorse or promote products derived from this software
     18  *    without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     30  * SUCH DAMAGE.
     31  *
     32  *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
     33  */
     34 
     35 #include <sys/malloc.h>
     36 #include <sys/pool.h>
     37 #include <sys/queue.h>
     38 
     39 /*
     40  * Mbufs are of a single size, MSIZE (sys/param.h), which
     41  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
     42  * MCLBYTES (also in sys/param.h), which has no additional overhead
     43  * and is used instead of the internal data area; this is done when
     44  * at least MINCLSIZE of data must be stored.
     45  */
     46 
     47 #define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
     48 #define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
     49 
     50 /* smallest amount to put in cluster */
     51 #define	MINCLSIZE	(MHLEN + MLEN + 1)
     52 #define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */
     53 
     54 /* Packet tags structure */
     55 struct m_tag {
     56 	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */
     57 	u_int16_t		m_tag_id;	/* Tag ID */
     58 	u_int16_t		m_tag_len;	/* Length of data */
     59 };
     60 
     61 /*
     62  * Macros for type conversion
     63  * mtod(m,t) -	convert mbuf pointer to data pointer of correct type
     64  */
     65 #define	mtod(m,t)	((t)((m)->m_data))
     66 
     67 /* header at beginning of each mbuf: */
     68 struct m_hdr {
     69 	struct	mbuf *mh_next;		/* next buffer in chain */
     70 	struct	mbuf *mh_nextpkt;	/* next chain in queue/record */
     71 	caddr_t	mh_data;		/* location of data */
     72 	u_int	mh_len;			/* amount of data in this mbuf */
     73 	short	mh_type;		/* type of data in this mbuf */
     74 	u_short	mh_flags;		/* flags; see below */
     75 };
     76 
     77 /* pf stuff */
     78 struct pkthdr_pf {
     79 	void		*hdr;		/* saved hdr pos in mbuf, for ECN */
     80 	void		*statekey;	/* pf stackside statekey */
     81 	u_int32_t	 qid;		/* queue id */
     82 	u_int16_t	 tag;		/* tag id */
     83 	u_int8_t	 flags;
     84 	u_int8_t	 routed;
     85 	u_int8_t	 prio;
     86 	u_int8_t	 pad[3];
     87 };
     88 
     89 /* pkthdr_pf.flags */
     90 #define	PF_TAG_GENERATED		0x01
     91 #define	PF_TAG_TRANSLATE_LOCALHOST	0x04
     92 #define	PF_TAG_DIVERTED			0x08
     93 #define	PF_TAG_DIVERTED_PACKET		0x10
     94 #define	PF_TAG_REROUTE			0x20
     95 #define	PF_TAG_REFRAGMENTED		0x40	/* refragmented ipv6 packet */
     96 
     97 /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
     98 struct	pkthdr {
     99 	struct ifnet		*rcvif;		/* rcv interface */
    100 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
    101 	int			 len;		/* total packet length */
    102 	u_int16_t		 tagsset;	/* mtags attached */
    103 	u_int16_t		 pad;
    104 	u_int16_t		 csum_flags;	/* checksum flags */
    105 	u_int16_t		 ether_vtag;	/* Ethernet 802.1p+Q vlan tag */
    106 	u_int			 rdomain;	/* routing domain id */
    107 	struct pkthdr_pf	 pf;
    108 };
    109 
    110 /* description of external storage mapped into mbuf, valid if M_EXT set */
    111 struct mbuf_ext {
    112 	caddr_t	ext_buf;		/* start of buffer */
    113 					/* free routine if not the usual */
    114 	void	(*ext_free)(caddr_t, u_int, void *);
    115 	void	*ext_arg;		/* argument for ext_free */
    116 	u_int	ext_size;		/* size of buffer, for ext_free */
    117 	int	ext_type;
    118 	struct ifnet* ext_ifp;
    119 	int	ext_backend;		/* backend pool the storage came from */
    120 	struct mbuf *ext_nextref;
    121 	struct mbuf *ext_prevref;
    122 #ifdef DEBUG
    123 	const char *ext_ofile;
    124 	const char *ext_nfile;
    125 	int ext_oline;
    126 	int ext_nline;
    127 #endif
    128 };
    129 
    130 struct mbuf {
    131 	struct	m_hdr m_hdr;
    132 	union {
    133 		struct {
    134 			struct	pkthdr MH_pkthdr;	/* M_PKTHDR set */
    135 			union {
    136 				struct	mbuf_ext MH_ext; /* M_EXT set */
    137 				char	MH_databuf[MHLEN];
    138 			} MH_dat;
    139 		} MH;
    140 		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
    141 	} M_dat;
    142 };
    143 #define	m_next		m_hdr.mh_next
    144 #define	m_len		m_hdr.mh_len
    145 #define	m_data		m_hdr.mh_data
    146 #define	m_type		m_hdr.mh_type
    147 #define	m_flags		m_hdr.mh_flags
    148 #define	m_nextpkt	m_hdr.mh_nextpkt
    149 #define	m_act		m_nextpkt
    150 #define	m_pkthdr	M_dat.MH.MH_pkthdr
    151 #define	m_ext		M_dat.MH.MH_dat.MH_ext
    152 #define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
    153 #define	m_dat		M_dat.M_databuf
    154 
    155 /* mbuf flags */
    156 #define	M_EXT		0x0001	/* has associated external storage */
    157 #define	M_PKTHDR	0x0002	/* start of record */
    158 #define	M_EOR		0x0004	/* end of record */
    159 #define M_CLUSTER	0x0008	/* external storage is a cluster */
    160 #define	M_PROTO1	0x0010	/* protocol-specific */
    161 
    162 /* mbuf pkthdr flags, also in m_flags */
    163 #define M_VLANTAG	0x0020	/* ether_vtag is valid */
    164 #define M_LOOP		0x0040	/* for Mbuf statistics */
    165 #define M_FILDROP	0x0080	/* dropped by bpf filter */
    166 #define M_BCAST		0x0100	/* send/received as link-level broadcast */
    167 #define M_MCAST		0x0200	/* send/received as link-level multicast */
    168 #define M_CONF		0x0400  /* payload was encrypted (ESP-transport) */
    169 #define M_AUTH		0x0800  /* payload was authenticated (AH or ESP auth) */
    170 #define M_TUNNEL	0x1000  /* IP-in-IP added by tunnel mode IPsec */
    171 #define M_AUTH_AH	0x2000  /* header was authenticated (AH) */
    172 #define M_COMP		0x4000  /* header was decompressed */
    173 #define M_LINK0		0x8000	/* link layer specific flag */
    174 
    175 /* flags copied when copying m_pkthdr */
    176 #define	M_COPYFLAGS	(M_PKTHDR|M_EOR|M_PROTO1|M_BCAST|M_MCAST|M_CONF|M_COMP|\
    177 			 M_AUTH|M_LOOP|M_TUNNEL|M_LINK0|M_VLANTAG|M_FILDROP)
    178 
    179 /* Checksumming flags */
    180 #define	M_IPV4_CSUM_OUT		0x0001	/* IPv4 checksum needed */
    181 #define M_TCP_CSUM_OUT		0x0002	/* TCP checksum needed */
    182 #define	M_UDP_CSUM_OUT		0x0004	/* UDP checksum needed */
    183 #define	M_IPV4_CSUM_IN_OK	0x0008	/* IPv4 checksum verified */
    184 #define	M_IPV4_CSUM_IN_BAD	0x0010	/* IPv4 checksum bad */
    185 #define	M_TCP_CSUM_IN_OK	0x0020	/* TCP/IPv4 checksum verified */
    186 #define	M_TCP_CSUM_IN_BAD	0x0040	/* TCP/IPv4 checksum bad */
    187 #define	M_UDP_CSUM_IN_OK	0x0080	/* UDP/IPv4 checksum verified */
    188 #define	M_UDP_CSUM_IN_BAD	0x0100	/* UDP/IPv4 checksum bad */
    189 #define	M_ICMP_CSUM_OUT		0x0200	/* ICMP checksum needed */
    190 #define	M_ICMP_CSUM_IN_OK	0x0400	/* ICMP checksum verified */
    191 #define	M_ICMP_CSUM_IN_BAD	0x0800	/* ICMP checksum bad */
    192 
    193 /* mbuf types */
    194 #define	MT_FREE		0	/* should be on free list */
    195 #define	MT_DATA		1	/* dynamic (data) allocation */
    196 #define	MT_HEADER	2	/* packet header */
    197 #define	MT_SONAME	3	/* socket name */
    198 #define	MT_SOOPTS	4	/* socket options */
    199 #define	MT_FTABLE	5	/* fragment reassembly header */
    200 #define	MT_CONTROL	6	/* extra-data protocol message */
    201 #define	MT_OOBDATA	7	/* expedited data  */
    202 
    203 /* flags to m_get/MGET */
    204 #define	M_DONTWAIT	M_NOWAIT
    205 #define	M_WAIT		M_WAITOK
    206 
    207 /*
    208  * mbuf allocation/deallocation macros:
    209  *
    210  *	MGET(struct mbuf *m, int how, int type)
    211  * allocates an mbuf and initializes it to contain internal data.
    212  *
    213  *	MGETHDR(struct mbuf *m, int how, int type)
    214  * allocates an mbuf and initializes it to contain a packet header
    215  * and internal data.
    216  */
    217 #define MGET(m, how, type) m = m_get((how), (type))
    218 
    219 #define MGETHDR(m, how, type) m = m_gethdr((how), (type))
    220 
    221 /*
    222  * Macros for tracking external storage associated with an mbuf.
    223  *
    224  * Note: add and delete reference must be called at splnet().
    225  */
    226 #ifdef DEBUG
    227 #define MCLREFDEBUGN(m, file, line) do {				\
    228 		(m)->m_ext.ext_nfile = (file);				\
    229 		(m)->m_ext.ext_nline = (line);				\
    230 	} while (/* CONSTCOND */ 0)
    231 #define MCLREFDEBUGO(m, file, line) do {				\
    232 		(m)->m_ext.ext_ofile = (file);				\
    233 		(m)->m_ext.ext_oline = (line);				\
    234 	} while (/* CONSTCOND */ 0)
    235 #else
    236 #define MCLREFDEBUGN(m, file, line)
    237 #define MCLREFDEBUGO(m, file, line)
    238 #endif
    239 
    240 #define	MCLISREFERENCED(m)	((m)->m_ext.ext_nextref != (m))
    241 
    242 #define	MCLADDREFERENCE(o, n)	do {					\
    243 		int ms = splnet();					\
    244 		(n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER));	\
    245 		(n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref;	\
    246 		(n)->m_ext.ext_prevref = (o);				\
    247 		(o)->m_ext.ext_nextref = (n);				\
    248 		(n)->m_ext.ext_nextref->m_ext.ext_prevref = (n);	\
    249 		splx(ms);						\
    250 		MCLREFDEBUGN((n), __FILE__, __LINE__);			\
    251 	} while (/* CONSTCOND */ 0)
    252 
    253 #define	MCLINITREFERENCE(m)	do {					\
    254 		(m)->m_ext.ext_prevref = (m);				\
    255 		(m)->m_ext.ext_nextref = (m);				\
    256 		MCLREFDEBUGO((m), __FILE__, __LINE__);			\
    257 		MCLREFDEBUGN((m), NULL, 0);				\
    258 	} while (/* CONSTCOND */ 0)
    259 
    260 /*
    261  * Macros for mbuf external storage.
    262  *
    263  * MEXTADD adds pre-allocated external storage to
    264  * a normal mbuf; the flag M_EXT is set.
    265  *
    266  * MCLGET allocates and adds an mbuf cluster to a normal mbuf;
    267  * the flag M_EXT is set upon success.
    268  */
    269 #define	MEXTADD(m, buf, size, type, free, arg) do {			\
    270 	(m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf);		\
    271 	(m)->m_flags |= M_EXT;						\
    272 	(m)->m_flags &= ~M_CLUSTER;					\
    273 	(m)->m_ext.ext_size = (size);					\
    274 	(m)->m_ext.ext_free = (free);					\
    275 	(m)->m_ext.ext_arg = (arg);					\
    276 	(m)->m_ext.ext_type = (type);					\
    277 	MCLINITREFERENCE(m);						\
    278 } while (/* CONSTCOND */ 0)
    279 
    280 #define MCLGET(m, how) (void) m_clget((m), (how), NULL, MCLBYTES)
    281 #define MCLGETI(m, how, ifp, l) m_clget((m), (how), (ifp), (l))
    282 
    283 /*
    284  * MFREE(struct mbuf *m, struct mbuf *n)
    285  * Free a single mbuf and associated external storage.
    286  * Place the successor, if any, in n.
    287  */
    288 #define	MFREE(m, n) n = m_free((m))
    289 
    290 /*
    291  * Move just m_pkthdr from from to to,
    292  * remove M_PKTHDR and clean flags/tags for from.
    293  */
    294 #define M_MOVE_HDR(to, from) do {					\
    295 	(to)->m_pkthdr = (from)->m_pkthdr;				\
    296 	(from)->m_flags &= ~M_PKTHDR;					\
    297 	SLIST_INIT(&(from)->m_pkthdr.tags);				\
    298 } while (/* CONSTCOND */ 0)
    299 
    300 /*
    301  * MOVE mbuf pkthdr from from to to.
    302  * from must have M_PKTHDR set, and to must be empty.
    303  */
    304 #define	M_MOVE_PKTHDR(to, from) do {					\
    305 	(to)->m_flags = ((to)->m_flags & (M_EXT | M_CLUSTER));		\
    306 	(to)->m_flags |= (from)->m_flags & M_COPYFLAGS;			\
    307 	M_MOVE_HDR((to), (from));					\
    308 	if (((to)->m_flags & M_EXT) == 0)				\
    309 		(to)->m_data = (to)->m_pktdat;				\
    310 } while (/* CONSTCOND */ 0)
    311 
    312 /*
    313  * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
    314  * an object of the specified size at the end of the mbuf, longword aligned.
    315  */
    316 #define	M_ALIGN(m, len) \
    317 	(m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1)
    318 /*
    319  * As above, for mbufs allocated with m_gethdr/MGETHDR
    320  * or initialized by M_MOVE_PKTHDR.
    321  */
    322 #define	MH_ALIGN(m, len) \
    323 	(m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1)
    324 
    325 /*
    326  * Determine if an mbuf's data area is read-only. This is true for
    327  * non-cluster external storage and for clusters that are being
    328  * referenced by more than one mbuf.
    329  */
    330 #define	M_READONLY(m)							\
    331 	(((m)->m_flags & M_EXT) != 0 &&					\
    332 	  (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m)))
    333 
    334 /*
    335  * Compute the amount of space available
    336  * before the current start of data in an mbuf.
    337  */
    338 #define	M_LEADINGSPACE(m) m_leadingspace(m)
    339 
    340 /*
    341  * Compute the amount of space available
    342  * after the end of data in an mbuf.
    343  */
    344 #define	M_TRAILINGSPACE(m) m_trailingspace(m)
    345 
    346 /*
    347  * Arrange to prepend space of size plen to mbuf m.
    348  * If a new mbuf must be allocated, how specifies whether to wait.
    349  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
    350  * is freed and m is set to NULL.
    351  */
    352 #define	M_PREPEND(m, plen, how) \
    353 		(m) = m_prepend((m), (plen), (how))
    354 
    355 /* length to m_copy to copy all */
    356 #define	M_COPYALL	1000000000
    357 
    358 /* compatibility with 4.3 */
    359 #define  m_copy(m, o, l)	m_copym((m), (o), (l), M_DONTWAIT)
    360 
    361 /*
    362  * Mbuf statistics.
    363  * For statistics related to mbuf and cluster allocations, see also the
    364  * pool headers (mbpool and mclpool).
    365  */
    366 struct mbstat {
    367 	u_long	_m_spare;	/* formerly m_mbufs */
    368 	u_long	_m_spare1;	/* formerly m_clusters */
    369 	u_long	_m_spare2;	/* spare field */
    370 	u_long	_m_spare3;	/* formely m_clfree - free clusters */
    371 	u_long	m_drops;	/* times failed to find space */
    372 	u_long	m_wait;		/* times waited for space */
    373 	u_long	m_drain;	/* times drained protocols for space */
    374 	u_short	m_mtypes[256];	/* type specific mbuf allocations */
    375 };
    376 
    377 #ifdef	_KERNEL
    378 
    379 extern	struct mbstat mbstat;
    380 extern	int nmbclust;			/* limit on the # of clusters */
    381 extern	int mblowat;			/* mbuf low water mark */
    382 extern	int mcllowat;			/* mbuf cluster low water mark */
    383 extern	int max_linkhdr;		/* largest link-level header */
    384 extern	int max_protohdr;		/* largest protocol header */
    385 extern	int max_hdr;			/* largest link+protocol header */
    386 extern	int max_datalen;		/* MHLEN - max_hdr */
    387 
    388 void	mbinit(void);
    389 struct	mbuf *m_copym2(struct mbuf *, int, int, int);
    390 struct	mbuf *m_copym(struct mbuf *, int, int, int);
    391 struct	mbuf *m_free(struct mbuf *);
    392 struct	mbuf *m_free_unlocked(struct mbuf *);
    393 struct	mbuf *m_get(int, int);
    394 struct	mbuf *m_getclr(int, int);
    395 struct	mbuf *m_gethdr(int, int);
    396 struct	mbuf *m_inithdr(struct mbuf *);
    397 int	      m_defrag(struct mbuf *, int);
    398 struct	mbuf *m_prepend(struct mbuf *, int, int);
    399 struct	mbuf *m_pulldown(struct mbuf *, int, int, int *);
    400 struct	mbuf *m_pullup(struct mbuf *, int);
    401 struct	mbuf *m_split(struct mbuf *, int, int);
    402 struct  mbuf *m_inject(struct mbuf *, int, int, int);
    403 struct  mbuf *m_getptr(struct mbuf *, int, int *);
    404 int	m_leadingspace(struct mbuf *);
    405 int	m_trailingspace(struct mbuf *);
    406 struct mbuf *m_clget(struct mbuf *, int, struct ifnet *, u_int);
    407 void	m_clsetwms(struct ifnet *, u_int, u_int, u_int);
    408 int	m_cldrop(struct ifnet *, int);
    409 void	m_clcount(struct ifnet *, int);
    410 void	m_cluncount(struct mbuf *, int);
    411 void	m_clinitifp(struct ifnet *);
    412 void	m_adj(struct mbuf *, int);
    413 int	m_copyback(struct mbuf *, int, int, const void *, int);
    414 void	m_freem(struct mbuf *);
    415 void	m_reclaim(void *, int);
    416 void	m_copydata(struct mbuf *, int, int, caddr_t);
    417 void	m_cat(struct mbuf *, struct mbuf *);
    418 struct mbuf *m_devget(char *, int, int, struct ifnet *,
    419 	    void (*)(const void *, void *, size_t));
    420 void	m_zero(struct mbuf *);
    421 int	m_apply(struct mbuf *, int, int,
    422 	    int (*)(caddr_t, caddr_t, unsigned int), caddr_t);
    423 int	m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
    424 
    425 /* Packet tag routines */
    426 struct m_tag *m_tag_get(int, int, int);
    427 void	m_tag_prepend(struct mbuf *, struct m_tag *);
    428 void	m_tag_delete(struct mbuf *, struct m_tag *);
    429 void	m_tag_delete_chain(struct mbuf *);
    430 struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
    431 struct m_tag *m_tag_copy(struct m_tag *, int);
    432 int	m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
    433 void	m_tag_init(struct mbuf *);
    434 struct m_tag *m_tag_first(struct mbuf *);
    435 struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
    436 
    437 /* Packet tag types */
    438 #define PACKET_TAG_IPSEC_IN_DONE	0x0001  /* IPsec applied, in */
    439 #define PACKET_TAG_IPSEC_OUT_DONE	0x0002  /* IPsec applied, out */
    440 #define PACKET_TAG_IPSEC_IN_CRYPTO_DONE	0x0004  /* NIC IPsec crypto done */
    441 #define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 0x0008  /* NIC IPsec crypto req'ed */
    442 #define PACKET_TAG_IPSEC_PENDING_TDB	0x0010  /* Reminder to do IPsec */
    443 #define PACKET_TAG_BRIDGE		0x0020  /* Bridge processing done */
    444 #define PACKET_TAG_GIF			0x0040  /* GIF processing done */
    445 #define PACKET_TAG_GRE			0x0080  /* GRE processing done */
    446 #define PACKET_TAG_DLT			0x0100 /* data link layer type */
    447 #define PACKET_TAG_PF_DIVERT		0x0200 /* pf(4) diverted packet */
    448 #define PACKET_TAG_PIPEX		0x0400 /* pipex context XXX */
    449 #define PACKET_TAG_PF_REASSEMBLED	0x0800 /* pf reassembled ipv6 packet */
    450 
    451 #endif
    452