@@ -175,7 +175,6 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
odp_buffer_pool_t pkt_pool)
{
ipsec_cache_entry_t *entry = stream->input.entry;
- odp_buffer_t bfr;
odp_packet_t pkt;
uint8_t *base;
uint8_t *data;
@@ -187,12 +186,10 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
stream_pkt_hdr_t *test;
uint i;
- /* Get buffer */
- bfr = odp_buffer_alloc(pkt_pool);
- if (ODP_BUFFER_INVALID == bfr)
+ /* Get packet */
+ pkt = odp_packet_alloc(pkt_pool, 0);
+ if (ODP_PACKET_INVALID == pkt)
return ODP_PACKET_INVALID;
- pkt = odp_packet_from_buffer(bfr);
- odp_packet_init(pkt);
base = odp_packet_data(pkt);
data = odp_packet_data(pkt);
@@ -19,6 +19,7 @@ extern "C" {
#endif
#include <odp_buffer.h>
+#include <odp_platform_types.h>
/** @defgroup odp_packet ODP PACKET
* Operations on a packet.
@@ -26,33 +27,73 @@ extern "C" {
*/
+/*
+ * Packet API v0.5 notes
+ * - Push/pull operations only on packet level
+ * - Push/pull within limits of segment headroom/tailroom/data lengths
+ * - Segment data length must be always at least one byte (i.e. there are no
+ * empty segments)
+ * - Head/tailroom content belong to packet content (in addition to data
+ * and meta-data) and thus is preserved over packet ownership changes.
+ * - _addr refer to a fixed address, which operations do not modify
+ * - _ptr refer to pointer to data, which may be modified by operations
+ */
+
+
+/*
+ *
+ * Alloc and free
+ * ********************************************************
+ *
+ */
+
/**
- * Allocate and initialize a packet buffer from a packet pool
+ * Allocate a packet from a buffer pool
*
- * @param pool_id Pool handle
+ * Allocates a packet of the requested length from the specified buffer pool.
+ * Pool must have been created with buffer type ODP_BUFFER_TYPE_PACKET. The
+ * packet is initialized with data pointers and lengths set according to the
+ * specified len, and the default headroom and tailroom length settings. All
+ * other packet metadata are set to their default values.
*
- * @note The pool must have been created with 'buf_type=ODP_BUFFER_TYPE_PACKET'
+ * @param pool Pool handle
+ * @param len Packet data length
*
- * @return Packet handle or ODP_PACKET_INVALID
+ * @return Handle of allocated packet
+ * @retval ODP_PACKET_INVALID Packet could not be allocated
+ *
+ * @note The default headroom and tailroom used for packets is specified by
+ * the ODP_CONFIG_PACKET_HEADROOM and ODP_CONFIG_PACKET_TAILROOM defines in
+ * odp_config.h.
*/
-odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_id);
+odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool, uint32_t len);
/**
- * Free a packet buffer back into the packet pool
+ * Free packet
*
- * @param pkt Packet handle
+ * Frees the packet into the buffer pool it was allocated from.
+ *
+ * @param pkt Packet handle
*/
void odp_packet_free(odp_packet_t pkt);
/**
- * Initialize the packet
+ * Reset packet
*
- * Needs to be called if the user allocates a packet buffer, i.e. the packet
- * has not been received from I/O through ODP.
+ * Resets all packet meta-data to their default values. Packet length is used
+ * to initialize pointers and lengths. It must be less than the total buffer
+ * length of the packet minus the default headroom length. Packet is not
+ * modified on failure.
*
- * @param pkt Packet handle
+ * @param pkt Packet handle
+ * @param len Packet data length
+ *
+ * @retval 0 Success
+ * @retval Non-zero Failure
+ *
+ * @see odp_packet_buf_len()
*/
-void odp_packet_init(odp_packet_t pkt);
+int odp_packet_reset(odp_packet_t pkt, uint32_t len);
/**
* Convert a buffer handle to a packet handle
@@ -169,6 +169,7 @@ static inline void packet_init(pool_entry_t *pool,
(pool->s.headroom + size);
}
+odp_packet_t _odp_packet_alloc(odp_buffer_pool_t pool_hdl);
#ifdef __cplusplus
}
@@ -21,34 +21,54 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
odph_ipv6hdr_t *ipv6, size_t *offset_out);
-odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_id)
+/*
+ *
+ * Alloc and free
+ * ********************************************************
+ *
+ */
+
+odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_hdl, uint32_t len)
{
- odp_packet_t pkt;
- odp_buffer_t buf;
+ pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
- buf = odp_buffer_alloc(pool_id);
- if (odp_unlikely(!odp_buffer_is_valid(buf)))
+ if (pool->s.params.buf_type != ODP_BUFFER_TYPE_PACKET)
return ODP_PACKET_INVALID;
- pkt = odp_packet_from_buffer(buf);
- odp_packet_init(pkt);
+ /* Handle special case for zero-length packets */
+ if (len == 0) {
+ odp_packet_t pkt =
+ (odp_packet_t)buffer_alloc(pool_hdl,
+ pool->s.params.buf_size);
+ if (pkt != ODP_PACKET_INVALID) {
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ uint32_t buf_size = pool->s.params.buf_size;
+ pkt_hdr->tailroom += buf_size;
+ pkt_hdr->frame_len -= buf_size;
+ }
- return pkt;
+ return pkt;
+ }
+
+ return (odp_packet_t)buffer_alloc(pool_hdl, len);
}
void odp_packet_free(odp_packet_t pkt)
{
- odp_buffer_t buf = odp_packet_to_buffer(pkt);
-
- odp_buffer_free(buf);
+ odp_buffer_free((odp_buffer_t)pkt);
}
-void odp_packet_init(odp_packet_t pkt)
+int odp_packet_reset(odp_packet_t pkt, uint32_t len)
{
odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
pool_entry_t *pool = odp_buf_to_pool(&pkt_hdr->buf_hdr);
+ uint32_t totsize = pool->s.headroom + len + pool->s.tailroom;
+
+ if (totsize > pkt_hdr->buf_hdr.size)
+ return -1;
- packet_init(pool, pkt_hdr, 0);
+ packet_init(pool, pkt_hdr, len);
+ return 0;
}
odp_packet_t odp_packet_from_buffer(odp_buffer_t buf)
@@ -404,3 +424,21 @@ size_t odp_packet_buf_size(odp_packet_t pkt)
return odp_buffer_size(buf);
}
+
+/*
+ *
+ * Internal Use Routines
+ * ********************************************************
+ *
+ */
+
+odp_packet_t _odp_packet_alloc(odp_buffer_pool_t pool_hdl)
+{
+ pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
+
+ if (pool->s.params.buf_type != ODP_BUFFER_TYPE_PACKET)
+ return ODP_PACKET_INVALID;
+
+ return (odp_packet_t)buffer_alloc(pool_hdl,
+ pool->s.params.buf_size);
+}
@@ -215,7 +215,7 @@ int setup_pkt_sock(pkt_sock_t *const pkt_sock, const char *netdev,
return -1;
pkt_sock->pool = pool;
- pkt = odp_packet_alloc(pool);
+ pkt = _odp_packet_alloc(pool);
if (!odp_packet_is_valid(pkt))
return -1;
@@ -332,7 +332,7 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock,
for (i = 0; i < len; i++) {
if (odp_likely(pkt == ODP_PACKET_INVALID)) {
- pkt = odp_packet_alloc(pkt_sock->pool);
+ pkt = _odp_packet_alloc(pkt_sock->pool);
if (odp_unlikely(pkt == ODP_PACKET_INVALID))
break;
}
@@ -430,7 +430,7 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock,
memset(msgvec, 0, sizeof(msgvec));
for (i = 0; i < (int)len; i++) {
- pkt_table[i] = odp_packet_alloc(pkt_sock->pool);
+ pkt_table[i] = _odp_packet_alloc(pkt_sock->pool);
if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
break;
@@ -605,7 +605,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring,
continue;
}
- pkt_table[i] = odp_packet_alloc(pool);
+ pkt_table[i] = _odp_packet_alloc(pool);
if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
break;
@@ -851,7 +851,7 @@ int setup_pkt_sock_mmap(pkt_sock_mmap_t *const pkt_sock, const char *netdev,
if (pool == ODP_BUFFER_POOL_INVALID)
return -1;
- pkt = odp_packet_alloc(pool);
+ pkt = _odp_packet_alloc(pool);
if (!odp_packet_is_valid(pkt))
return -1;