xref: /nrf52832-nimble/packages/NimBLE-latest/porting/nimble/include/os/os_mbuf.h (revision 042d53a763ad75cb1465103098bb88c245d95138)
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