blob: 881ddba65ff9d83542790e37bacfabe9f26fd55c [file] [log] [blame]
/**
* Copyright (c) 2015 Runtime Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _OS_MBUF_H
#define _OS_MBUF_H
#include "os/os_eventq.h"
/**
* A mbuf pool from which to allocate mbufs. This contains a pointer to the os
* mempool to allocate mbufs out of, the total number of elements in the pool,
* and the amount of "user" data in a non-packet header mbuf. The total pool
* size, in bytes, should be:
* os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
*/
struct os_mbuf_pool {
/**
* Total length of the databuf in each mbuf. This is the size of the
* mempool block, minus the mbuf header
*/
uint16_t omp_databuf_len;
/**
* Total number of memblock's allocated in this mempool.
*/
uint16_t omp_mbuf_count;
/**
* The memory pool which to allocate mbufs out of
*/
struct os_mempool *omp_pool;
};
/**
* A packet header structure that preceeds the mbuf packet headers.
*/
struct os_mbuf_pkthdr {
/**
* Overall length of the packet.
*/
uint16_t omp_len;
/**
* Flags
*/
uint16_t omp_flags;
/**
* Next packet in the mbuf chain.
*/
STAILQ_ENTRY(os_mbuf_pkthdr) omp_next;
};
/**
* Chained memory buffer.
*/
struct os_mbuf {
/**
* Current pointer to data in the structure
*/
uint8_t *om_data;
/**
* Flags associated with this buffer, see OS_MBUF_F_* defintions
*/
uint8_t om_flags;
/**
* Length of packet header
*/
uint8_t om_pkthdr_len;
/**
* Length of data in this buffer
*/
uint16_t om_len;
/**
* The mbuf pool this mbuf was allocated out of
*/
struct os_mbuf_pool *om_omp;
/**
* Pointer to next entry in the chained memory buffer
*/
SLIST_ENTRY(os_mbuf) om_next;
/**
* Pointer to the beginning of the data, after this buffer
*/
uint8_t om_databuf[0];
};
struct os_mqueue {
STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
struct os_event mq_ev;
};
/*
* Given a flag number, provide the mask for it
*
* @param __n The number of the flag in the mask
*/
#define OS_MBUF_F_MASK(__n) (1 << (__n))
/*
* Checks whether a given mbuf is a packet header mbuf
*
* @param __om The mbuf to check
*/
#define OS_MBUF_IS_PKTHDR(__om) \
((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
/* Get a packet header pointer given an mbuf pointer */
#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
/* Given a mbuf packet header pointer, return a pointer to the mbuf */
#define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
(struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
/*
* Access the data of a mbuf, and cast it to type
*
* @param __om The mbuf to access, and cast
* @param __type The type to cast it to
*/
#define OS_MBUF_DATA(__om, __type) \
(__type) ((__om)->om_data)
/*
* Called by OS_MBUF_LEADINGSPACE() macro
*/
static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf *om)
{
uint16_t startoff;
uint16_t leadingspace;
startoff = 0;
if (OS_MBUF_IS_PKTHDR(om)) {
startoff = om->om_pkthdr_len;
}
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
((uint8_t *) &om->om_databuf[0] + startoff));
return (leadingspace);
}
/**
* Returns the leading space (space at the beginning) of the mbuf.
* Works on both packet header, and regular mbufs, as it accounts
* for the additional space allocated to the packet header.
*
* @param __omp Is the mbuf pool (which contains packet header length.)
* @param __om Is the mbuf in that pool to get the leadingspace for
*
* @return Amount of leading space available in the mbuf
*/
#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf *om)
{
struct os_mbuf_pool *omp;
omp = om->om_omp;
return (&om->om_databuf[0] + omp->omp_databuf_len) - om->om_data;
}
/**
* Returns the trailing space (space at the end) of the mbuf.
* Works on both packet header and regular mbufs.
*
* @param __omp The mbuf pool for this mbuf
* @param __om Is the mbuf in that pool to get trailing space for
*
* @return The amount of trailing space available in the mbuf
*/
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
/* Mbuf queue functions */
/* Initialize a mbuf queue */
int os_mqueue_init(struct os_mqueue *, void *arg);
/* Get an element from a mbuf queue */
struct os_mbuf *os_mqueue_get(struct os_mqueue *);
/* Put an element in a mbuf queue */
int os_mqueue_put(struct os_mqueue *, struct os_eventq *, struct os_mbuf *);
/* Initialize a mbuf pool */
int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
uint16_t, uint16_t);
/* Allocate a new mbuf out of the os_mbuf_pool */
struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
/* Allocate a new packet header mbuf out of the os_mbuf_pool */
struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
uint8_t pkthdr_len);
/* Duplicate a mbuf from the pool */
struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
struct os_mbuf * os_mbuf_off(struct os_mbuf *om, int off, int *out_off);
/* Copy data from an mbuf to a flat buffer. */
int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
/* Append data onto a mbuf */
int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
/* Free a mbuf */
int os_mbuf_free(struct os_mbuf *mb);
/* Free a mbuf chain */
int os_mbuf_free_chain(struct os_mbuf *om);
void os_mbuf_adj(struct os_mbuf *mp, int req_len);
int os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data,
int len);
struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
#endif /* _OS_MBUF_H */