1 /*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * @(#)mbuf.h 8.5 (Berkeley) 2/19/95
31 * $FreeBSD: releng/10.1/sys/sys/mbuf.h 269047 2014-07-24 06:03:45Z kevlo $
32 */
33
34 #ifndef _SYS_MBUF_0_H_
35 #define _SYS_MBUF_0_H_
36
37 #if (__CONFIG_MBUF_IMPL_MODE == 0)
38
39 #include <stdint.h>
40 #ifdef __CONFIG_ARCH_DUAL_CORE
41 #include "sys/ducc/ducc_addr.h"
42 #endif
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 /*
49 * Callback structure
50 */
51 struct m_cb {
52 void *func;
53 void *arg;
54 };
55
56 /*
57 * Record/packet header in first mbuf of chain; always valid and M_PKTHDR is set.
58 * Size : 24
59 */
60 struct pkthdr {
61 void *rcvif; /* rcv interface */
62 int32_t len; /* total packet length */
63
64 union {
65 uint8_t eigth[8];
66 uint16_t sixteen[4];
67 uint32_t thirtytwo[2];
68 uint64_t sixtyfour[1];
69 uintptr_t unintptr[1];
70 void *ptr;
71 } PH_per;
72
73 struct m_cb cb;
74 };
75
76 struct ext_info {
77 uint8_t eigth[32];
78 };
79
80 #define ether_vtag PH_per.sixteen[0]
81 #define PH_vt PH_per
82 #define vt_nrecs sixteen[0]
83 #define tso_segsz PH_per.sixteen[1]
84 #define csum_phsum PH_per.sixteen[2]
85 #define csum_data PH_per.thirtytwo[1]
86
87 /*
88 * The core of the mbuf object along with some shortcut defines for practical
89 * purposes.
90 */
91 struct mbuf { // Size : 48 + 32 = 80
92 /*
93 * Header present at the beginning of every mbuf.
94 * Size : 24
95 */
96 uint8_t *m_buf; /* a continuous buffer */ // useless now
97 struct mbuf *m_nextpkt; /* next chain in queue/record */
98 uint8_t *m_data; /* location of data */
99 int32_t m_len; /* amount of data in this mbuf */
100 uint16_t m_headspace; /* empty space available at the head */
101 uint16_t m_tailspace; /* empty space available at the tail */
102 uint32_t m_type :8, /* type of data in this mbuf */ // use as flag
103 m_flags :24; /* flags; see below */
104 /*** End of the mbuf header ***/
105
106 struct pkthdr m_pkthdr; /* M_PKTHDR always set */
107 struct ext_info m_ext_info; /* extend info */
108 };
109
110 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
111
112 #define MBUF_HEAD_SPACE 68 /* reserved head space in mbuf::m_buf, align to 4 */
113 #define MBUF_TAIL_SPACE 16 /* reserved tail space in mbuf::m_buf, align to 4 */
114
115 /*
116 * mbuf flags of global significance and layer crossing.
117 * Those of only protocol/layer specific significance are to be mapped
118 * to M_PROTO[1-12] and cleared at layer handoff boundaries.
119 * NB: Limited to the lower 24 bits.
120 */
121 #define M_EXT 0x00000001 /* has associated external storage */
122 #define M_PKTHDR 0x00000002 /* start of record */ // always set
123 #define M_EOR 0x00000004 /* end of record */
124 #define M_RDONLY 0x00000008 /* associated data is marked read-only */
125 #define M_BCAST 0x00000010 /* send/received as link-level broadcast */
126 #define M_MCAST 0x00000020 /* send/received as link-level multicast */
127 #define M_PROMISC 0x00000040 /* packet was not for us */
128 #define M_VLANTAG 0x00000080 /* ether_vtag is valid */
129 #define M_FLOWID 0x00000100 /* deprecated: flowid is valid */
130 #define M_NOFREE 0x00000200 /* do not free mbuf, embedded in cluster */
131
132 #define M_PROTO1 0x00001000 /* protocol-specific */
133 #define M_PROTO2 0x00002000 /* protocol-specific */
134 #define M_PROTO3 0x00004000 /* protocol-specific */
135 #define M_PROTO4 0x00008000 /* protocol-specific */
136 #define M_PROTO5 0x00010000 /* protocol-specific */
137 #define M_PROTO6 0x00020000 /* protocol-specific */
138 #define M_PROTO7 0x00040000 /* protocol-specific */
139 #define M_PROTO8 0x00080000 /* protocol-specific */
140 #define M_PROTO9 0x00100000 /* protocol-specific */
141 #define M_PROTO10 0x00200000 /* protocol-specific */
142 #define M_PROTO11 0x00400000 /* protocol-specific */
143 #define M_PROTO12 0x00800000 /* protocol-specific */
144
145 /*
146 * Flags to purge when crossing layers.
147 */
148 #define M_PROTOFLAGS \
149 (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\
150 M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
151
152 /*
153 * Flags preserved when copying m_pkthdr.
154 */
155 #define M_COPYFLAGS \
156 (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
157 M_PROTOFLAGS)
158
159 /*
160 * Mbuf flag description for use with printf(9) %b identifier.
161 */
162 #define M_FLAG_BITS \
163 "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_BCAST\6M_MCAST" \
164 "\7M_PROMISC\10M_VLANTAG\11M_FLOWID"
165 #define M_FLAG_PROTOBITS \
166 "\15M_PROTO1\16M_PROTO2\17M_PROTO3\20M_PROTO4\21M_PROTO5" \
167 "\22M_PROTO6\23M_PROTO7\24M_PROTO8\25M_PROTO9\26M_PROTO10" \
168 "\27M_PROTO11\30M_PROTO12"
169 #define M_FLAG_PRINTF (M_FLAG_BITS M_FLAG_PROTOBITS)
170
171
172 /*
173 * mbuf types describing the content of the mbuf (including external storage).
174 */
175 #define MT_NOTMBUF 0 /* USED INTERNALLY ONLY! Object is not mbuf */
176 #define MT_DATA 1 /* dynamic (data) allocation */
177 #define MT_HEADER MT_DATA /* packet header, use M_PKTHDR instead */
178
179 #define MT_VENDOR1 4 /* for vendor-internal use */
180 #define MT_VENDOR2 5 /* for vendor-internal use */
181 #define MT_VENDOR3 6 /* for vendor-internal use */
182 #define MT_VENDOR4 7 /* for vendor-internal use */
183
184 #define MT_SONAME 8 /* socket name */
185
186 #define MT_EXP1 9 /* for experimental use */
187 #define MT_EXP2 10 /* for experimental use */
188 #define MT_EXP3 11 /* for experimental use */
189 #define MT_EXP4 12 /* for experimental use */
190
191 #define MT_CONTROL 14 /* extra-data protocol message */
192 #define MT_OOBDATA 15 /* expedited data */
193 #define MT_NTYPES 16 /* number of mbuf types for mbtypes[] */
194
195 #define MT_NOINIT 255 /* Not a type but a flag to allocate
196 a non-initialized mbuf */
197
198 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
199
200 #ifdef __CONFIG_ARCH_DUAL_CORE
201 /*
202 * NB: mbuf is allocated from net core, pointer conversion MUST be done when
203 * transfer mbuf from app core to net core, or vice versa.
204 */
205
206 #ifdef __CONFIG_ARCH_NET_CORE
207 /* convert mbuf's pointers in net core, the new mbuf is used by net core */
208 #define MBUF_APP2NET(m) \
209 do { \
210 (m) = (struct mbuf *)DUCC_NETMEM_APP2NET(m); \
211 (m)->m_data = (uint8_t *)DUCC_NETMEM_APP2NET((m)->m_data); \
212 } while (0)
213
214 /* convert mbuf's pointers in net core, the new mbuf is used by app core */
215 #define MBUF_NET2APP(m) \
216 do { \
217 (m)->m_data = (uint8_t *)DUCC_NETMEM_NET2APP((m)->m_data); \
218 (m) = (struct mbuf *)DUCC_NETMEM_NET2APP(m); \
219 } while (0)
220 #endif /* __CONFIG_ARCH_NET_CORE */
221
222 #ifdef __CONFIG_ARCH_APP_CORE
223 /* convert mbuf's pointers in app core, the new mbuf is used by net core */
224 #define MBUF_APP2NET(m) \
225 do { \
226 (m)->m_data = (uint8_t *)DUCC_NETMEM_APP2NET((m)->m_data); \
227 (m) = (struct mbuf *)DUCC_NETMEM_APP2NET(m); \
228 } while (0)
229
230 /* convert mbuf's pointers in app core, the new mbuf is used by app core */
231 #define MBUF_NET2APP(m) \
232 do { \
233 (m) = (struct mbuf *)DUCC_NETMEM_NET2APP(m); \
234 (m)->m_data = (uint8_t *)DUCC_NETMEM_NET2APP((m)->m_data); \
235 } while (0)
236 #endif /* __CONFIG_ARCH_APP_CORE */
237
238 #endif /* __CONFIG_ARCH_DUAL_CORE */
239
240 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
241
242 struct mbuf *mb_get(int len, int tx);
243 void mb_free(struct mbuf *m);
244 int mb_adj(struct mbuf *m, int req_len);
245 int mb_copydata(const struct mbuf *m, int off, int len, uint8_t *cp);
246 struct mbuf *mb_dup(struct mbuf *m);
247 struct mbuf *mb_pullup(struct mbuf *m, int len); // NOT really support!
248 struct mbuf *mb_split(struct mbuf *m0, int len0);
249 int mb_append(struct mbuf *m, int len, const uint8_t *cp);
250 int mb_reserve(struct mbuf *m, int len, uint16_t headspace, uint16_t tailspace);
251
252 #define m_freem(m) mb_free(m)
253 #define m_adj(m, l) mb_adj(m, l)
254 #define m_copydata(m, o, l, p) mb_copydata(m, o, l, p)
255 #define m_dup(m, h) mb_dup(m)
256 #define m_pullup(m, l) mb_pullup(m, l)
257 #define m_split(m, l, w) mb_split(m, l)
258 #define m_append(m, l, c) mb_append(m, l, c)
259
260 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
261
262 /*
263 * Macro for type conversion: convert mbuf pointer to data pointer of correct
264 * type:
265 *
266 * mtod(m, t) -- Convert mbuf pointer to data pointer of correct type.
267 */
268 #define mtod(m, t) ((t)((m)->m_data))
269
270 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
271
272 /*
273 * Compute the amount of space available before the current start of data in
274 * an mbuf.
275 */
276 #define M_LEADINGSPACE(m) ((m)->m_headspace)
277
278 /*
279 * Compute the amount of space available after the end of data in an mbuf.
280 */
281 #define M_TRAILINGSPACE(m) ((m)->m_tailspace)
282
283
284 /*
285 * Arrange to prepend space of size plen to mbuf m. If a new mbuf must be
286 * allocated, how specifies whether to wait. If the allocation fails, the
287 * original mbuf chain is freed and m is set to NULL.
288 */
289 #define MB_PREPEND(m, plen) \
290 do { \
291 int _plen = (plen); \
292 if (_plen >= 0 && M_LEADINGSPACE(m) >= _plen) { \
293 (m)->m_headspace -= (_plen); \
294 (m)->m_data -= (_plen); \
295 (m)->m_len += (_plen); \
296 (m)->m_pkthdr.len += (_plen); \
297 } else { \
298 mb_free(m); \
299 (m) = NULL; \
300 } \
301 } while (0)
302
303 #define M_PREPEND(m, plen, how) MB_PREPEND(m, plen)
304
m_clrprotoflags(struct mbuf * m)305 static __inline void m_clrprotoflags(struct mbuf *m)
306 {
307 m->m_flags &= ~M_PROTOFLAGS;
308 }
309
310 /* option of limiting memory usage */
311 #define MBUF_OPT_LIMIT_MEM 1
312
313 #if MBUF_OPT_LIMIT_MEM
314 /*
315 * Flags for @param tx in mb_get(), which also saved in struct mbuf::m_type
316 * - MBUF_GET_FLAG_LIMIT_TX: memory usage limit by MBUF_TX_MEM_MAX
317 * - MBUF_GET_FLAG_LIMIT_RX: memory usage limit by MBUF_RX_MEM_MAX
318 */
319 #define MBUF_GET_FLAG_MASK (0xF << 4)
320 #define MBUF_GET_FLAG_LIMIT_TX (1 << 4)
321 #define MBUF_GET_FLAG_LIMIT_RX (1 << 5)
322
323 void mb_mem_set_limit(uint32_t tx, uint32_t rx, uint32_t txrx);
324 void mb_mem_get_limit(uint32_t *tx, uint32_t *rx, uint32_t *txrx);
325
326 #else /* MBUF_OPT_LIMIT_MEM */
327
328 #define MBUF_GET_FLAG_LIMIT_TX 0
329 #define MBUF_GET_FLAG_LIMIT_RX 0
330
331 #endif /* MBUF_OPT_LIMIT_MEM */
332
333 #if 0 // only for test, no need to implement
334 #define MCLSHIFT 11 /* convert bytes to mbuf clusters */
335 #define MCLBYTES (1 << MCLSHIFT) /* size of an mbuf cluster */
336
337 /*
338 * Concatenate mbuf chain n to m.
339 * Both chains must be of the same type (e.g. MT_DATA).
340 * Any m_pkthdr is not updated.
341 */
342 void m_cat(struct mbuf *m, struct mbuf *n);
343 struct mbuf *m_getcl(int how, short type, int flags);
344 void m_align(struct mbuf *m, int len);
345 #endif
346
347 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
348
349 #ifdef __cplusplus
350 }
351 #endif
352
353 #endif /* (__CONFIG_MBUF_IMPL_MODE == 0) */
354 #endif /* !_SYS_MBUF_0_H_ */
355