1*042d53a7SEvalZero /*
2*042d53a7SEvalZero * Licensed to the Apache Software Foundation (ASF) under one
3*042d53a7SEvalZero * or more contributor license agreements. See the NOTICE file
4*042d53a7SEvalZero * distributed with this work for additional information
5*042d53a7SEvalZero * regarding copyright ownership. The ASF licenses this file
6*042d53a7SEvalZero * to you under the Apache License, Version 2.0 (the
7*042d53a7SEvalZero * "License"); you may not use this file except in compliance
8*042d53a7SEvalZero * with the License. You may obtain a copy of the License at
9*042d53a7SEvalZero *
10*042d53a7SEvalZero * http://www.apache.org/licenses/LICENSE-2.0
11*042d53a7SEvalZero *
12*042d53a7SEvalZero * Unless required by applicable law or agreed to in writing,
13*042d53a7SEvalZero * software distributed under the License is distributed on an
14*042d53a7SEvalZero * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15*042d53a7SEvalZero * KIND, either express or implied. See the License for the
16*042d53a7SEvalZero * specific language governing permissions and limitations
17*042d53a7SEvalZero * under the License.
18*042d53a7SEvalZero */
19*042d53a7SEvalZero
20*042d53a7SEvalZero
21*042d53a7SEvalZero /**
22*042d53a7SEvalZero * @addtogroup OSKernel
23*042d53a7SEvalZero * @{
24*042d53a7SEvalZero * @defgroup OSMbuf Chained Memory Buffers
25*042d53a7SEvalZero * @{
26*042d53a7SEvalZero */
27*042d53a7SEvalZero
28*042d53a7SEvalZero
29*042d53a7SEvalZero #ifndef _OS_MBUF_H
30*042d53a7SEvalZero #define _OS_MBUF_H
31*042d53a7SEvalZero
32*042d53a7SEvalZero #include "os/os.h"
33*042d53a7SEvalZero
34*042d53a7SEvalZero #ifdef __cplusplus
35*042d53a7SEvalZero extern "C" {
36*042d53a7SEvalZero #endif
37*042d53a7SEvalZero
38*042d53a7SEvalZero /**
39*042d53a7SEvalZero * A mbuf pool from which to allocate mbufs. This contains a pointer to the os
40*042d53a7SEvalZero * mempool to allocate mbufs out of, the total number of elements in the pool,
41*042d53a7SEvalZero * and the amount of "user" data in a non-packet header mbuf. The total pool
42*042d53a7SEvalZero * size, in bytes, should be:
43*042d53a7SEvalZero * os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
44*042d53a7SEvalZero */
45*042d53a7SEvalZero struct os_mbuf_pool {
46*042d53a7SEvalZero /**
47*042d53a7SEvalZero * Total length of the databuf in each mbuf. This is the size of the
48*042d53a7SEvalZero * mempool block, minus the mbuf header
49*042d53a7SEvalZero */
50*042d53a7SEvalZero uint16_t omp_databuf_len;
51*042d53a7SEvalZero /**
52*042d53a7SEvalZero * The memory pool which to allocate mbufs out of
53*042d53a7SEvalZero */
54*042d53a7SEvalZero struct os_mempool *omp_pool;
55*042d53a7SEvalZero
56*042d53a7SEvalZero STAILQ_ENTRY(os_mbuf_pool) omp_next;
57*042d53a7SEvalZero };
58*042d53a7SEvalZero
59*042d53a7SEvalZero
60*042d53a7SEvalZero /**
61*042d53a7SEvalZero * A packet header structure that preceeds the mbuf packet headers.
62*042d53a7SEvalZero */
63*042d53a7SEvalZero struct os_mbuf_pkthdr {
64*042d53a7SEvalZero /**
65*042d53a7SEvalZero * Overall length of the packet.
66*042d53a7SEvalZero */
67*042d53a7SEvalZero uint16_t omp_len;
68*042d53a7SEvalZero /**
69*042d53a7SEvalZero * Flags
70*042d53a7SEvalZero */
71*042d53a7SEvalZero uint16_t omp_flags;
72*042d53a7SEvalZero
73*042d53a7SEvalZero STAILQ_ENTRY(os_mbuf_pkthdr) omp_next;
74*042d53a7SEvalZero };
75*042d53a7SEvalZero
76*042d53a7SEvalZero /**
77*042d53a7SEvalZero * Chained memory buffer.
78*042d53a7SEvalZero */
79*042d53a7SEvalZero struct os_mbuf {
80*042d53a7SEvalZero /**
81*042d53a7SEvalZero * Current pointer to data in the structure
82*042d53a7SEvalZero */
83*042d53a7SEvalZero uint8_t *om_data;
84*042d53a7SEvalZero /**
85*042d53a7SEvalZero * Flags associated with this buffer, see OS_MBUF_F_* defintions
86*042d53a7SEvalZero */
87*042d53a7SEvalZero uint8_t om_flags;
88*042d53a7SEvalZero /**
89*042d53a7SEvalZero * Length of packet header
90*042d53a7SEvalZero */
91*042d53a7SEvalZero uint8_t om_pkthdr_len;
92*042d53a7SEvalZero /**
93*042d53a7SEvalZero * Length of data in this buffer
94*042d53a7SEvalZero */
95*042d53a7SEvalZero uint16_t om_len;
96*042d53a7SEvalZero
97*042d53a7SEvalZero /**
98*042d53a7SEvalZero * The mbuf pool this mbuf was allocated out of
99*042d53a7SEvalZero */
100*042d53a7SEvalZero struct os_mbuf_pool *om_omp;
101*042d53a7SEvalZero
102*042d53a7SEvalZero SLIST_ENTRY(os_mbuf) om_next;
103*042d53a7SEvalZero
104*042d53a7SEvalZero /**
105*042d53a7SEvalZero * Pointer to the beginning of the data, after this buffer
106*042d53a7SEvalZero */
107*042d53a7SEvalZero uint8_t om_databuf[0];
108*042d53a7SEvalZero };
109*042d53a7SEvalZero
110*042d53a7SEvalZero /**
111*042d53a7SEvalZero * Structure representing a queue of mbufs.
112*042d53a7SEvalZero */
113*042d53a7SEvalZero struct os_mqueue {
114*042d53a7SEvalZero STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
115*042d53a7SEvalZero /** Event to post when new buffers are available on the queue. */
116*042d53a7SEvalZero struct ble_npl_event mq_ev;
117*042d53a7SEvalZero };
118*042d53a7SEvalZero
119*042d53a7SEvalZero /*
120*042d53a7SEvalZero * Given a flag number, provide the mask for it
121*042d53a7SEvalZero *
122*042d53a7SEvalZero * @param __n The number of the flag in the mask
123*042d53a7SEvalZero */
124*042d53a7SEvalZero #define OS_MBUF_F_MASK(__n) (1 << (__n))
125*042d53a7SEvalZero
126*042d53a7SEvalZero /*
127*042d53a7SEvalZero * Checks whether a given mbuf is a packet header mbuf
128*042d53a7SEvalZero *
129*042d53a7SEvalZero * @param __om The mbuf to check
130*042d53a7SEvalZero */
131*042d53a7SEvalZero #define OS_MBUF_IS_PKTHDR(__om) \
132*042d53a7SEvalZero ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
133*042d53a7SEvalZero
134*042d53a7SEvalZero /** Get a packet header pointer given an mbuf pointer */
135*042d53a7SEvalZero #define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
136*042d53a7SEvalZero ((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
137*042d53a7SEvalZero
138*042d53a7SEvalZero /** Given a mbuf packet header pointer, return a pointer to the mbuf */
139*042d53a7SEvalZero #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
140*042d53a7SEvalZero (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
141*042d53a7SEvalZero
142*042d53a7SEvalZero /**
143*042d53a7SEvalZero * Gets the length of an entire mbuf chain. The specified mbuf must have a
144*042d53a7SEvalZero * packet header.
145*042d53a7SEvalZero */
146*042d53a7SEvalZero #define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len)
147*042d53a7SEvalZero
148*042d53a7SEvalZero /**
149*042d53a7SEvalZero * Access the data of a mbuf, and cast it to type
150*042d53a7SEvalZero *
151*042d53a7SEvalZero * @param __om The mbuf to access, and cast
152*042d53a7SEvalZero * @param __type The type to cast it to
153*042d53a7SEvalZero */
154*042d53a7SEvalZero #define OS_MBUF_DATA(__om, __type) \
155*042d53a7SEvalZero (__type) ((__om)->om_data)
156*042d53a7SEvalZero
157*042d53a7SEvalZero /**
158*042d53a7SEvalZero * Access the "user header" in the head of an mbuf chain.
159*042d53a7SEvalZero *
160*042d53a7SEvalZero * @param om Pointer to the head of an mbuf chain.
161*042d53a7SEvalZero */
162*042d53a7SEvalZero #define OS_MBUF_USRHDR(om) \
163*042d53a7SEvalZero (void *)((uint8_t *)om + sizeof (struct os_mbuf) + \
164*042d53a7SEvalZero sizeof (struct os_mbuf_pkthdr))
165*042d53a7SEvalZero
166*042d53a7SEvalZero /**
167*042d53a7SEvalZero * Retrieves the length of the user header in an mbuf.
168*042d53a7SEvalZero *
169*042d53a7SEvalZero * @param om Pointer to the mbuf to query.
170*042d53a7SEvalZero */
171*042d53a7SEvalZero #define OS_MBUF_USRHDR_LEN(om) \
172*042d53a7SEvalZero ((om)->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr))
173*042d53a7SEvalZero
174*042d53a7SEvalZero
175*042d53a7SEvalZero /** @cond INTERNAL_HIDDEN */
176*042d53a7SEvalZero
177*042d53a7SEvalZero /*
178*042d53a7SEvalZero * Called by OS_MBUF_LEADINGSPACE() macro
179*042d53a7SEvalZero */
180*042d53a7SEvalZero static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf * om)181*042d53a7SEvalZero _os_mbuf_leadingspace(struct os_mbuf *om)
182*042d53a7SEvalZero {
183*042d53a7SEvalZero uint16_t startoff;
184*042d53a7SEvalZero uint16_t leadingspace;
185*042d53a7SEvalZero
186*042d53a7SEvalZero startoff = 0;
187*042d53a7SEvalZero if (OS_MBUF_IS_PKTHDR(om)) {
188*042d53a7SEvalZero startoff = om->om_pkthdr_len;
189*042d53a7SEvalZero }
190*042d53a7SEvalZero
191*042d53a7SEvalZero leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
192*042d53a7SEvalZero ((uint8_t *) &om->om_databuf[0] + startoff));
193*042d53a7SEvalZero
194*042d53a7SEvalZero return (leadingspace);
195*042d53a7SEvalZero }
196*042d53a7SEvalZero
197*042d53a7SEvalZero /** @endcond */
198*042d53a7SEvalZero
199*042d53a7SEvalZero /**
200*042d53a7SEvalZero * Returns the leading space (space at the beginning) of the mbuf.
201*042d53a7SEvalZero * Works on both packet header, and regular mbufs, as it accounts
202*042d53a7SEvalZero * for the additional space allocated to the packet header.
203*042d53a7SEvalZero *
204*042d53a7SEvalZero * @param __omp Is the mbuf pool (which contains packet header length.)
205*042d53a7SEvalZero * @param __om Is the mbuf in that pool to get the leadingspace for
206*042d53a7SEvalZero *
207*042d53a7SEvalZero * @return Amount of leading space available in the mbuf
208*042d53a7SEvalZero */
209*042d53a7SEvalZero #define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
210*042d53a7SEvalZero
211*042d53a7SEvalZero
212*042d53a7SEvalZero /** @cond INTERNAL_HIDDEN */
213*042d53a7SEvalZero
214*042d53a7SEvalZero /* Called by OS_MBUF_TRAILINGSPACE() macro. */
215*042d53a7SEvalZero static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf * om)216*042d53a7SEvalZero _os_mbuf_trailingspace(struct os_mbuf *om)
217*042d53a7SEvalZero {
218*042d53a7SEvalZero struct os_mbuf_pool *omp;
219*042d53a7SEvalZero
220*042d53a7SEvalZero omp = om->om_omp;
221*042d53a7SEvalZero
222*042d53a7SEvalZero return (&om->om_databuf[0] + omp->omp_databuf_len) -
223*042d53a7SEvalZero (om->om_data + om->om_len);
224*042d53a7SEvalZero }
225*042d53a7SEvalZero
226*042d53a7SEvalZero /** @endcond */
227*042d53a7SEvalZero
228*042d53a7SEvalZero /**
229*042d53a7SEvalZero * Returns the trailing space (space at the end) of the mbuf.
230*042d53a7SEvalZero * Works on both packet header and regular mbufs.
231*042d53a7SEvalZero *
232*042d53a7SEvalZero * @param __omp The mbuf pool for this mbuf
233*042d53a7SEvalZero * @param __om Is the mbuf in that pool to get trailing space for
234*042d53a7SEvalZero *
235*042d53a7SEvalZero * @return The amount of trailing space available in the mbuf
236*042d53a7SEvalZero */
237*042d53a7SEvalZero #define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
238*042d53a7SEvalZero
239*042d53a7SEvalZero
240*042d53a7SEvalZero /**
241*042d53a7SEvalZero * Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
242*042d53a7SEvalZero * particular task's event queue. Mqueues form a helper API around a common
243*042d53a7SEvalZero * paradigm: wait on an event queue until at least one packet is available,
244*042d53a7SEvalZero * then process a queue of packets.
245*042d53a7SEvalZero *
246*042d53a7SEvalZero * When mbufs are available on the queue, an event OS_EVENT_T_MQUEUE_DATA
247*042d53a7SEvalZero * will be posted to the task's mbuf queue.
248*042d53a7SEvalZero *
249*042d53a7SEvalZero * @param mq The mqueue to initialize
250*042d53a7SEvalZero * @param ev_cb The callback to associate with the mqeueue
251*042d53a7SEvalZero * event. Typically, this callback pulls each
252*042d53a7SEvalZero * packet off the mqueue and processes them.
253*042d53a7SEvalZero * @param arg The argument to associate with the mqueue event.
254*042d53a7SEvalZero *
255*042d53a7SEvalZero * @return 0 on success, non-zero on failure.
256*042d53a7SEvalZero */
257*042d53a7SEvalZero int os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg);
258*042d53a7SEvalZero
259*042d53a7SEvalZero /**
260*042d53a7SEvalZero * Remove and return a single mbuf from the mbuf queue. Does not block.
261*042d53a7SEvalZero *
262*042d53a7SEvalZero * @param mq The mbuf queue to pull an element off of.
263*042d53a7SEvalZero *
264*042d53a7SEvalZero * @return The next mbuf in the queue, or NULL if queue has no mbufs.
265*042d53a7SEvalZero */
266*042d53a7SEvalZero struct os_mbuf *os_mqueue_get(struct os_mqueue *);
267*042d53a7SEvalZero
268*042d53a7SEvalZero /**
269*042d53a7SEvalZero * Adds a packet (i.e. packet header mbuf) to an mqueue. The event associated
270*042d53a7SEvalZero * with the mqueue gets posted to the specified eventq.
271*042d53a7SEvalZero *
272*042d53a7SEvalZero * @param mq The mbuf queue to append the mbuf to.
273*042d53a7SEvalZero * @param evq The event queue to post an event to.
274*042d53a7SEvalZero * @param m The mbuf to append to the mbuf queue.
275*042d53a7SEvalZero *
276*042d53a7SEvalZero * @return 0 on success, non-zero on failure.
277*042d53a7SEvalZero */
278*042d53a7SEvalZero int os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *);
279*042d53a7SEvalZero
280*042d53a7SEvalZero /**
281*042d53a7SEvalZero * MSYS is a system level mbuf registry. Allows the system to share
282*042d53a7SEvalZero * packet buffers amongst the various networking stacks that can be running
283*042d53a7SEvalZero * simultaeneously.
284*042d53a7SEvalZero *
285*042d53a7SEvalZero * Mbuf pools are created in the system initialization code, and then when
286*042d53a7SEvalZero * a mbuf is allocated out of msys, it will try and find the best fit based
287*042d53a7SEvalZero * upon estimated mbuf size.
288*042d53a7SEvalZero *
289*042d53a7SEvalZero * os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
290*042d53a7SEvalZero * allocate mbufs out of it.
291*042d53a7SEvalZero *
292*042d53a7SEvalZero * @param new_pool The pool to register with MSYS
293*042d53a7SEvalZero *
294*042d53a7SEvalZero * @return 0 on success, non-zero on failure
295*042d53a7SEvalZero */
296*042d53a7SEvalZero int os_msys_register(struct os_mbuf_pool *);
297*042d53a7SEvalZero
298*042d53a7SEvalZero /**
299*042d53a7SEvalZero * Allocate a mbuf from msys. Based upon the data size requested,
300*042d53a7SEvalZero * os_msys_get() will choose the mbuf pool that has the best fit.
301*042d53a7SEvalZero *
302*042d53a7SEvalZero * @param dsize The estimated size of the data being stored in the mbuf
303*042d53a7SEvalZero * @param leadingspace The amount of leadingspace to allocate in the mbuf
304*042d53a7SEvalZero *
305*042d53a7SEvalZero * @return A freshly allocated mbuf on success, NULL on failure.
306*042d53a7SEvalZero */
307*042d53a7SEvalZero struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace);
308*042d53a7SEvalZero
309*042d53a7SEvalZero /**
310*042d53a7SEvalZero * De-registers all mbuf pools from msys.
311*042d53a7SEvalZero */
312*042d53a7SEvalZero void os_msys_reset(void);
313*042d53a7SEvalZero
314*042d53a7SEvalZero /**
315*042d53a7SEvalZero * Allocate a packet header structure from the MSYS pool. See
316*042d53a7SEvalZero * os_msys_register() for a description of MSYS.
317*042d53a7SEvalZero *
318*042d53a7SEvalZero * @param dsize The estimated size of the data being stored in the mbuf
319*042d53a7SEvalZero * @param user_hdr_len The length to allocate for the packet header structure
320*042d53a7SEvalZero *
321*042d53a7SEvalZero * @return A freshly allocated mbuf on success, NULL on failure.
322*042d53a7SEvalZero */
323*042d53a7SEvalZero struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
324*042d53a7SEvalZero
325*042d53a7SEvalZero /**
326*042d53a7SEvalZero * Count the number of blocks in all the mbuf pools that are allocated.
327*042d53a7SEvalZero *
328*042d53a7SEvalZero * @return total number of blocks allocated in Msys
329*042d53a7SEvalZero */
330*042d53a7SEvalZero int os_msys_count(void);
331*042d53a7SEvalZero
332*042d53a7SEvalZero /**
333*042d53a7SEvalZero * Return the number of free blocks in Msys
334*042d53a7SEvalZero *
335*042d53a7SEvalZero * @return Number of free blocks available in Msys
336*042d53a7SEvalZero */
337*042d53a7SEvalZero int os_msys_num_free(void);
338*042d53a7SEvalZero
339*042d53a7SEvalZero /**
340*042d53a7SEvalZero * Initialize a pool of mbufs.
341*042d53a7SEvalZero *
342*042d53a7SEvalZero * @param omp The mbuf pool to initialize
343*042d53a7SEvalZero * @param mp The memory pool that will hold this mbuf pool
344*042d53a7SEvalZero * @param buf_len The length of the buffer itself.
345*042d53a7SEvalZero * @param nbufs The number of buffers in the pool
346*042d53a7SEvalZero *
347*042d53a7SEvalZero * @return 0 on success, error code on failure.
348*042d53a7SEvalZero */
349*042d53a7SEvalZero int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
350*042d53a7SEvalZero uint16_t, uint16_t);
351*042d53a7SEvalZero
352*042d53a7SEvalZero /**
353*042d53a7SEvalZero * Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized
354*042d53a7SEvalZero * prior to being returned.
355*042d53a7SEvalZero *
356*042d53a7SEvalZero * @param omp The mbuf pool to return the packet from
357*042d53a7SEvalZero * @param leadingspace The amount of leadingspace to put before the data
358*042d53a7SEvalZero * section by default.
359*042d53a7SEvalZero *
360*042d53a7SEvalZero * @return An initialized mbuf on success, and NULL on failure.
361*042d53a7SEvalZero */
362*042d53a7SEvalZero struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
363*042d53a7SEvalZero
364*042d53a7SEvalZero /**
365*042d53a7SEvalZero * Allocate a new packet header mbuf out of the os_mbuf_pool.
366*042d53a7SEvalZero *
367*042d53a7SEvalZero * @param omp The mbuf pool to allocate out of
368*042d53a7SEvalZero * @param user_pkthdr_len The packet header length to reserve for the caller.
369*042d53a7SEvalZero *
370*042d53a7SEvalZero * @return A freshly allocated mbuf on success, NULL on failure.
371*042d53a7SEvalZero */
372*042d53a7SEvalZero struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
373*042d53a7SEvalZero uint8_t pkthdr_len);
374*042d53a7SEvalZero
375*042d53a7SEvalZero /**
376*042d53a7SEvalZero * Duplicate a chain of mbufs. Return the start of the duplicated chain.
377*042d53a7SEvalZero *
378*042d53a7SEvalZero * @param omp The mbuf pool to duplicate out of
379*042d53a7SEvalZero * @param om The mbuf chain to duplicate
380*042d53a7SEvalZero *
381*042d53a7SEvalZero * @return A pointer to the new chain of mbufs
382*042d53a7SEvalZero */
383*042d53a7SEvalZero struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
384*042d53a7SEvalZero
385*042d53a7SEvalZero /**
386*042d53a7SEvalZero * Locates the specified absolute offset within an mbuf chain. The offset
387*042d53a7SEvalZero * can be one past than the total length of the chain, but no greater.
388*042d53a7SEvalZero *
389*042d53a7SEvalZero * @param om The start of the mbuf chain to seek within.
390*042d53a7SEvalZero * @param off The absolute address to find.
391*042d53a7SEvalZero * @param out_off On success, this points to the relative offset
392*042d53a7SEvalZero * within the returned mbuf.
393*042d53a7SEvalZero *
394*042d53a7SEvalZero * @return The mbuf containing the specified offset on
395*042d53a7SEvalZero * success.
396*042d53a7SEvalZero * NULL if the specified offset is out of bounds.
397*042d53a7SEvalZero */
398*042d53a7SEvalZero struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off,
399*042d53a7SEvalZero uint16_t *out_off);
400*042d53a7SEvalZero
401*042d53a7SEvalZero
402*042d53a7SEvalZero /*
403*042d53a7SEvalZero * Copy data from an mbuf chain starting "off" bytes from the beginning,
404*042d53a7SEvalZero * continuing for "len" bytes, into the indicated buffer.
405*042d53a7SEvalZero *
406*042d53a7SEvalZero * @param m The mbuf chain to copy from
407*042d53a7SEvalZero * @param off The offset into the mbuf chain to begin copying from
408*042d53a7SEvalZero * @param len The length of the data to copy
409*042d53a7SEvalZero * @param dst The destination buffer to copy into
410*042d53a7SEvalZero *
411*042d53a7SEvalZero * @return 0 on success;
412*042d53a7SEvalZero * -1 if the mbuf does not contain enough data.
413*042d53a7SEvalZero */
414*042d53a7SEvalZero int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
415*042d53a7SEvalZero
416*042d53a7SEvalZero /**
417*042d53a7SEvalZero * Append data onto a mbuf
418*042d53a7SEvalZero *
419*042d53a7SEvalZero * @param om The mbuf to append the data onto
420*042d53a7SEvalZero * @param data The data to append onto the mbuf
421*042d53a7SEvalZero * @param len The length of the data to append
422*042d53a7SEvalZero *
423*042d53a7SEvalZero * @return 0 on success, and an error code on failure
424*042d53a7SEvalZero */
425*042d53a7SEvalZero int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
426*042d53a7SEvalZero
427*042d53a7SEvalZero /**
428*042d53a7SEvalZero * Reads data from one mbuf and appends it to another. On error, the specified
429*042d53a7SEvalZero * data range may be partially appended. Neither mbuf is required to contain
430*042d53a7SEvalZero * an mbuf packet header.
431*042d53a7SEvalZero *
432*042d53a7SEvalZero * @param dst The mbuf to append to.
433*042d53a7SEvalZero * @param src The mbuf to copy data from.
434*042d53a7SEvalZero * @param src_off The absolute offset within the source mbuf
435*042d53a7SEvalZero * chain to read from.
436*042d53a7SEvalZero * @param len The number of bytes to append.
437*042d53a7SEvalZero *
438*042d53a7SEvalZero * @return 0 on success;
439*042d53a7SEvalZero * OS_EINVAL if the specified range extends beyond
440*042d53a7SEvalZero * the end of the source mbuf chain.
441*042d53a7SEvalZero */
442*042d53a7SEvalZero int os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
443*042d53a7SEvalZero uint16_t src_off, uint16_t len);
444*042d53a7SEvalZero
445*042d53a7SEvalZero /**
446*042d53a7SEvalZero * Release a mbuf back to the pool
447*042d53a7SEvalZero *
448*042d53a7SEvalZero * @param omp The Mbuf pool to release back to
449*042d53a7SEvalZero * @param om The Mbuf to release back to the pool
450*042d53a7SEvalZero *
451*042d53a7SEvalZero * @return 0 on success, -1 on failure
452*042d53a7SEvalZero */
453*042d53a7SEvalZero int os_mbuf_free(struct os_mbuf *mb);
454*042d53a7SEvalZero
455*042d53a7SEvalZero /**
456*042d53a7SEvalZero * Free a chain of mbufs
457*042d53a7SEvalZero *
458*042d53a7SEvalZero * @param omp The mbuf pool to free the chain of mbufs into
459*042d53a7SEvalZero * @param om The starting mbuf of the chain to free back into the pool
460*042d53a7SEvalZero *
461*042d53a7SEvalZero * @return 0 on success, -1 on failure
462*042d53a7SEvalZero */
463*042d53a7SEvalZero int os_mbuf_free_chain(struct os_mbuf *om);
464*042d53a7SEvalZero
465*042d53a7SEvalZero /**
466*042d53a7SEvalZero * Adjust the length of a mbuf, trimming either from the head or the tail
467*042d53a7SEvalZero * of the mbuf.
468*042d53a7SEvalZero *
469*042d53a7SEvalZero * @param mp The mbuf chain to adjust
470*042d53a7SEvalZero * @param req_len The length to trim from the mbuf. If positive, trims
471*042d53a7SEvalZero * from the head of the mbuf, if negative, trims from the
472*042d53a7SEvalZero * tail of the mbuf.
473*042d53a7SEvalZero */
474*042d53a7SEvalZero void os_mbuf_adj(struct os_mbuf *mp, int req_len);
475*042d53a7SEvalZero
476*042d53a7SEvalZero
477*042d53a7SEvalZero /**
478*042d53a7SEvalZero * Performs a memory compare of the specified region of an mbuf chain against a
479*042d53a7SEvalZero * flat buffer.
480*042d53a7SEvalZero *
481*042d53a7SEvalZero * @param om The start of the mbuf chain to compare.
482*042d53a7SEvalZero * @param off The offset within the mbuf chain to start the
483*042d53a7SEvalZero * comparison.
484*042d53a7SEvalZero * @param data The flat buffer to compare.
485*042d53a7SEvalZero * @param len The length of the flat buffer.
486*042d53a7SEvalZero *
487*042d53a7SEvalZero * @return 0 if both memory regions are identical;
488*042d53a7SEvalZero * A memcmp return code if there is a mismatch;
489*042d53a7SEvalZero * INT_MAX if the mbuf is too short.
490*042d53a7SEvalZero */
491*042d53a7SEvalZero int os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len);
492*042d53a7SEvalZero
493*042d53a7SEvalZero /**
494*042d53a7SEvalZero * Compares the contents of two mbuf chains. The ranges of the two chains to
495*042d53a7SEvalZero * be compared are specified via the two offset parameters and the len
496*042d53a7SEvalZero * parameter. Neither mbuf chain is required to contain a packet header.
497*042d53a7SEvalZero *
498*042d53a7SEvalZero * @param om1 The first mbuf chain to compare.
499*042d53a7SEvalZero * @param offset1 The absolute offset within om1 at which to
500*042d53a7SEvalZero * start the comparison.
501*042d53a7SEvalZero * @param om2 The second mbuf chain to compare.
502*042d53a7SEvalZero * @param offset2 The absolute offset within om2 at which to
503*042d53a7SEvalZero * start the comparison.
504*042d53a7SEvalZero * @param len The number of bytes to compare.
505*042d53a7SEvalZero *
506*042d53a7SEvalZero * @return 0 if both mbuf segments are identical;
507*042d53a7SEvalZero * A memcmp() return code if the segment contents
508*042d53a7SEvalZero * differ;
509*042d53a7SEvalZero * INT_MAX if a specified range extends beyond the
510*042d53a7SEvalZero * end of its corresponding mbuf chain.
511*042d53a7SEvalZero */
512*042d53a7SEvalZero int os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
513*042d53a7SEvalZero const struct os_mbuf *om2, uint16_t offset2,
514*042d53a7SEvalZero uint16_t len);
515*042d53a7SEvalZero
516*042d53a7SEvalZero /**
517*042d53a7SEvalZero * Increases the length of an mbuf chain by adding data to the front. If there
518*042d53a7SEvalZero * is insufficient room in the leading mbuf, additional mbufs are allocated and
519*042d53a7SEvalZero * prepended as necessary. If this function fails to allocate an mbuf, the
520*042d53a7SEvalZero * entire chain is freed.
521*042d53a7SEvalZero *
522*042d53a7SEvalZero * The specified mbuf chain does not need to contain a packet header.
523*042d53a7SEvalZero *
524*042d53a7SEvalZero * @param omp The mbuf pool to allocate from.
525*042d53a7SEvalZero * @param om The head of the mbuf chain.
526*042d53a7SEvalZero * @param len The number of bytes to prepend.
527*042d53a7SEvalZero *
528*042d53a7SEvalZero * @return The new head of the chain on success;
529*042d53a7SEvalZero * NULL on failure.
530*042d53a7SEvalZero */
531*042d53a7SEvalZero struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
532*042d53a7SEvalZero
533*042d53a7SEvalZero /**
534*042d53a7SEvalZero * Prepends a chunk of empty data to the specified mbuf chain and ensures the
535*042d53a7SEvalZero * chunk is contiguous. If either operation fails, the specified mbuf chain is
536*042d53a7SEvalZero * freed and NULL is returned.
537*042d53a7SEvalZero *
538*042d53a7SEvalZero * @param om The mbuf chain to prepend to.
539*042d53a7SEvalZero * @param len The number of bytes to prepend and pullup.
540*042d53a7SEvalZero *
541*042d53a7SEvalZero * @return The modified mbuf on success;
542*042d53a7SEvalZero * NULL on failure (and the mbuf chain is freed).
543*042d53a7SEvalZero */
544*042d53a7SEvalZero struct os_mbuf *os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len);
545*042d53a7SEvalZero
546*042d53a7SEvalZero /**
547*042d53a7SEvalZero * Copies the contents of a flat buffer into an mbuf chain, starting at the
548*042d53a7SEvalZero * specified destination offset. If the mbuf is too small for the source data,
549*042d53a7SEvalZero * it is extended as necessary. If the destination mbuf contains a packet
550*042d53a7SEvalZero * header, the header length is updated.
551*042d53a7SEvalZero *
552*042d53a7SEvalZero * @param omp The mbuf pool to allocate from.
553*042d53a7SEvalZero * @param om The mbuf chain to copy into.
554*042d53a7SEvalZero * @param off The offset within the chain to copy to.
555*042d53a7SEvalZero * @param src The source buffer to copy from.
556*042d53a7SEvalZero * @param len The number of bytes to copy.
557*042d53a7SEvalZero *
558*042d53a7SEvalZero * @return 0 on success; nonzero on failure.
559*042d53a7SEvalZero */
560*042d53a7SEvalZero int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
561*042d53a7SEvalZero
562*042d53a7SEvalZero /**
563*042d53a7SEvalZero * Attaches a second mbuf chain onto the end of the first. If the first chain
564*042d53a7SEvalZero * contains a packet header, the header's length is updated. If the second
565*042d53a7SEvalZero * chain has a packet header, its header is cleared.
566*042d53a7SEvalZero *
567*042d53a7SEvalZero * @param first The mbuf chain being attached to.
568*042d53a7SEvalZero * @param second The mbuf chain that gets attached.
569*042d53a7SEvalZero */
570*042d53a7SEvalZero void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
571*042d53a7SEvalZero
572*042d53a7SEvalZero
573*042d53a7SEvalZero /**
574*042d53a7SEvalZero * Increases the length of an mbuf chain by the specified amount. If there is
575*042d53a7SEvalZero * not sufficient room in the last buffer, a new buffer is allocated and
576*042d53a7SEvalZero * appended to the chain. It is an error to request more data than can fit in
577*042d53a7SEvalZero * a single buffer.
578*042d53a7SEvalZero *
579*042d53a7SEvalZero * @param omp
580*042d53a7SEvalZero * @param om The head of the chain to extend.
581*042d53a7SEvalZero * @param len The number of bytes to extend by.
582*042d53a7SEvalZero *
583*042d53a7SEvalZero * @return A pointer to the new data on success;
584*042d53a7SEvalZero * NULL on failure.
585*042d53a7SEvalZero */
586*042d53a7SEvalZero void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
587*042d53a7SEvalZero
588*042d53a7SEvalZero /**
589*042d53a7SEvalZero * Rearrange a mbuf chain so that len bytes are contiguous,
590*042d53a7SEvalZero * and in the data area of an mbuf (so that OS_MBUF_DATA() will
591*042d53a7SEvalZero * work on a structure of size len.) Returns the resulting
592*042d53a7SEvalZero * mbuf chain on success, free's it and returns NULL on failure.
593*042d53a7SEvalZero *
594*042d53a7SEvalZero * If there is room, it will add up to "max_protohdr - len"
595*042d53a7SEvalZero * extra bytes to the contiguous region, in an attempt to avoid being
596*042d53a7SEvalZero * called next time.
597*042d53a7SEvalZero *
598*042d53a7SEvalZero * @param omp The mbuf pool to take the mbufs out of
599*042d53a7SEvalZero * @param om The mbuf chain to make contiguous
600*042d53a7SEvalZero * @param len The number of bytes in the chain to make contiguous
601*042d53a7SEvalZero *
602*042d53a7SEvalZero * @return The contiguous mbuf chain on success, NULL on failure.
603*042d53a7SEvalZero */
604*042d53a7SEvalZero struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len);
605*042d53a7SEvalZero
606*042d53a7SEvalZero
607*042d53a7SEvalZero /**
608*042d53a7SEvalZero * Removes and frees empty mbufs from the front of a chain. If the chain
609*042d53a7SEvalZero * contains a packet header, it is preserved.
610*042d53a7SEvalZero *
611*042d53a7SEvalZero * @param om The mbuf chain to trim.
612*042d53a7SEvalZero *
613*042d53a7SEvalZero * @return The head of the trimmed mbuf chain.
614*042d53a7SEvalZero */
615*042d53a7SEvalZero struct os_mbuf *os_mbuf_trim_front(struct os_mbuf *om);
616*042d53a7SEvalZero
617*042d53a7SEvalZero #ifdef __cplusplus
618*042d53a7SEvalZero }
619*042d53a7SEvalZero #endif
620*042d53a7SEvalZero
621*042d53a7SEvalZero #endif /* _OS_MBUF_H */
622*042d53a7SEvalZero
623*042d53a7SEvalZero
624*042d53a7SEvalZero /**
625*042d53a7SEvalZero * @} OSMbuf
626*042d53a7SEvalZero * @} OSKernel
627*042d53a7SEvalZero */
628