If you need urgent consulting help click here
Packet Management
Overview
Network packets are the main data the networking stack manipulates. Such data is represented through the net_pkt structure which provides a means to hold the packet, write and read it, as well as necessary metadata for the core to hold important information. Such an object is called net_pkt in this document.
The data structure and the whole API around it are defined in include/zephyr/net/net_pkt.h.
Architectural notes
There are two network packets flows within the stack, TX for the transmission path, and RX for the reception one. In both paths, each net_pkt is written and read from the beginning to the end, or more specifically from the headers to the payload.
Memory management
Allocation
All net_pkt objects come from a pre-defined pool of struct net_pkt. Such pool is defined via
NET_PKT_SLAB_DEFINE(name, count)
Note, however, one will rarely have to use it, as the core provides already two pools, one for the TX path and one for the RX path.
Allocating a raw net_pkt can be done through:
pkt = net_pkt_alloc(timeout);
However, by its nature, a raw net_pkt is useless without a buffer and needs various metadata information to become relevant as well. It requires at least to get the network interface it is meant to be sent through or through which it was received. As this is a very common operation, a helper exist:
pkt = net_pkt_alloc_on_iface(iface, timeout);
A more complete allocator exists, where both the net_pkt and its buffer can be allocated at once:
pkt = net_pkt_alloc_with_buffer(iface, size, family, proto, timeout);
See below how the buffer is allocated.
Buffer allocation
The net_pkt object does not define its own buffer, but instead uses an
existing object for this: net_buf
. (See
Network Buffer for more information). However, it mostly
hides the usage of such a buffer because net_pkt brings network
awareness to buffer allocation and, as we will see later, its
operation too.
To allocate a buffer, a net_pkt needs to have at least its network interface set. This works if the family of the packet is unknown at the time of buffer allocation. Then one could do:
net_pkt_alloc_buffer(pkt, size, proto, timeout);
Where proto could be 0 if unknown (there is no IPPROTO_UNSPEC).
As seen previously, the net_pkt and its buffer can be allocated at
once via net_pkt_alloc_with_buffer()
. It is actually the most
widely used allocator.
The network interface, the family, and the protocol of the packet are used by the buffer allocation to determine if the requested size can be allocated. Indeed, the allocator will use the network interface to know the MTU and then the family and protocol for the headers space (if only these 2 are specified). If the whole fits within the MTU, the allocated space will be of the requested size plus, eventually, the headers space. If there is insufficient MTU space, the requested size will be shrunk so the possible headers space and new size will fit within the MTU.
For instance, on an Ethernet network interface, with an MTU of 1500 bytes:
pkt = net_pkt_alloc_with_buffer(iface, 800, AF_INET4, IPPROTO_UDP, K_FOREVER);
will successfully allocate 800 + 20 + 8 bytes of buffer for the new net_pkt where:
pkt = net_pkt_alloc_with_buffer(iface, 1600, AF_INET4, IPPROTO_UDP, K_FOREVER);
will successfully allocate 1500 bytes, and where 20 + 8 bytes (IPv4 + UDP headers) will not be used for the payload.
On the receiving side, when the family and protocol are not known:
pkt = net_pkt_rx_alloc_with_buffer(iface, 800, AF_UNSPEC, 0, K_FOREVER);
will allocate 800 bytes and no extra header space. But a:
pkt = net_pkt_rx_alloc_with_buffer(iface, 1600, AF_UNSPEC, 0, K_FOREVER);
will allocate 1514 bytes, the MTU + Ethernet header space.
One can increase the amount of buffer space allocated by calling
net_pkt_alloc_buffer()
, as it will take into account the
existing buffer. It will also account for the header space if
net_pkt’s family is a valid one, as well as the proto parameter. In
that case, the newly allocated buffer space will be appended to the
existing one, and not inserted in the front. Note however such a use
case is rather limited. Usually, one should know from the start how
much size should be requested.
Deallocation
Each net_pkt is reference counted. At allocation, the reference is set
to 1. The reference count can be incremented with
net_pkt_ref()
or decremented with
net_pkt_unref()
. When the count drops to zero the buffer is
also un-referenced and net_pkt is automatically placed back into the
free net_pkt_slabs
If net_pkt’s buffer is needed even after net_pkt deallocation, one will need to reference once more all the chain of net_buf before calling last net_pkt_unref. See Network Buffer for more information.
Operations
There are two ways to access the net_pkt buffer, explained in the following sections: basic read/write access and data access, the latter being the preferred way.
Read and Write access
As said earlier, though net_pkt uses net_buf for its buffer, it provides its own API to access it. Indeed, a network packet might be scattered over a chain of net_buf objects, the functions provided by net_buf are then limited for such case. Instead, net_pkt provides functions which hide all the complexity of potential non-contiguous access.
Data movement into the buffer is made through a cursor maintained within each net_pkt. All read/write operations affect this cursor. Note as well that read or write functions are strict on their length parameters: if it cannot r/w the given length it will fail. Length is not interpreted as an upper limit, it is instead the exact amount of data that must be read or written.
As there are two paths, TX and RX, there are two access modes: write and overwrite. This might sound a bit unusual, but is in fact simple and provides flexibility.
In write mode, whatever is written in the buffer affects the length of actual data present in the buffer. Buffer length should not be confused with the buffer size which is a limit any mode cannot pass. In overwrite mode then, whatever is written must happen on valid data, and will not affect the buffer length. By default, a newly allocated net_pkt is on write mode, and its cursor points to the beginning of its buffer.
Let’s see now, step by step, the functions and how they behave depending on the mode.
When freshly allocated with a buffer of 500 bytes, a net_pkt has 0 length, which means no valid data is in its buffer. One could verify this by:
len = net_pkt_get_len(pkt);
Now, let’s write 8 bytes:
net_pkt_write(pkt, data, 8);
The buffer length is now 8 bytes. There are various helpers to write a byte, or big endian uint16_t, uint32_t.
net_pkt_write_u8(pkt, &foo);
net_pkt_write_be16(pkt, &ba);
net_pkt_write_be32(pkt, &bar);
Logically, net_pkt’s length is now 15. But if we try to read at this point, it will fail because there is nothing to read at the cursor where we are at in the net_pkt. It is possible, while in write mode, to read what has been already written by resetting the cursor of the net_pkt. For instance:
net_pkt_cursor_init(pkt);
net_pkt_read(pkt, data, 15);
This will reset the cursor of the pkt to the beginning of the buffer and then let you read the actual 15 bytes present. The cursor is then again pointing at the end of the buffer.
To set a large area with the same byte, a memset function is provided:
net_pkt_memset(pkt, 0, 5);
Our net_pkt has now a length of 20 bytes.
Switching between modes can be achieved via
net_pkt_set_overwrite()
function. It is possible to switch
mode back and forth at any time. The net_pkt will be set to overwrite
and its cursor reset:
net_pkt_set_overwrite(pkt, true);
net_pkt_cursor_init(pkt);
Now the same operators can be used, but it will be limited to the existing data in the buffer, i.e. 20 bytes.
If it is necessary to know how much space is available in the net_pkt call:
net_pkt_available_buffer(pkt);
Or, if headers space needs to be accounted for, call:
net_pkt_available_payload_buffer(pkt, proto);
If you want to place the cursor at a known position use the function
net_pkt_skip()
. For example, to go after the IP header, use:
net_pkt_cursor_init(pkt);
net_pkt_skip(pkt, net_pkt_ip_header_len(pkt));
Data access
Though the API shown previously is rather simple, it involves always copying things to and from the net_pkt buffer. In many occasions, it is more relevant to access the information stored in the buffer contiguously, especially with network packets which embed headers.
These headers are, most of the time, a known fixed set of bytes. It is then more natural to have a structure representing a certain type of header. In addition to this, if it is known the header size appears in a contiguous area of the buffer, it will be way more efficient to cast the actual position in the buffer to the type of header. Either for reading or writing the fields of such header, accessing it directly will save memory.
Net pkt comes with a dedicated API for this, built on top of the previously described API. It is able to handle both contiguous and non-contiguous access transparently.
There are two macros used to define a data access descriptor:
NET_PKT_DATA_ACCESS_DEFINE
when it is not possible to
tell if the data will be in a contiguous area, and
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE
when
it is guaranteed the data is in a contiguous area.
Let’s take the example of IP and UDP. Both IPv4 and IPv6 headers are always found at the beginning of the packet and are small enough to fit in a net_buf of 128 bytes (for instance, though 64 bytes could be chosen).
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv4_access, struct net_ipv4_hdr);
struct net_ipv4_hdr *ipv4_hdr;
ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(pkt, &ipv4_acess);
It would be the same for struct net_ipv4_hdr. For a UDP header it is likely not to be in a contiguous area in IPv6 for instance so:
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
struct net_udp_hdr *udp_hdr;
udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access);
At this point, the cursor of the net_pkt points at the beginning of the requested data. On the RX path, these headers will be read but not modified so to proceed further the cursor needs to advance past the data. There is a function dedicated for this:
net_pkt_acknowledge_data(pkt, &ipv4_access);
On the TX path, however, the header fields have been modified. In such a case:
net_pkt_set_data(pkt, &ipv4_access);
If the data are in a contiguous area, it will advance the cursor
relevantly. If not, it will write the data and the cursor will be
updated. Note that net_pkt_set_data()
could be used in the RX
path as well, but it is slightly faster to use
net_pkt_acknowledge_data()
as this one does not care about
contiguity at all, it just advances the cursor via
net_pkt_skip()
directly.
API Reference
- group net_pkt
Network packet management library.
Defines
-
NET_PKT_SLAB_DEFINE(name, count)
Create a net_pkt slab.
A net_pkt slab is used to store meta-information about network packets. It must be coupled with a data fragment pool (:c:macro:
NET_PKT_DATA_POOL_DEFINE
) used to store the actual packet data. The macro can be used by an application to define additional custom per-context TX packet slabs (see :c:func:net_context_setup_pools
).- Parameters
name – Name of the slab.
count – Number of net_pkt in this slab.
-
NET_PKT_TX_SLAB_DEFINE(name, count)
-
NET_PKT_DATA_POOL_DEFINE(name, count)
Create a data fragment net_buf pool.
A net_buf pool is used to store actual data for network packets. It must be coupled with a net_pkt slab (:c:macro:
NET_PKT_SLAB_DEFINE
) used to store the packet meta-information. The macro can be used by an application to define additional custom per-context TX packet pools (see :c:func:net_context_setup_pools
).- Parameters
name – Name of the pool.
count – Number of net_buf in this pool.
-
net_pkt_print_frags(pkt)
Print fragment list and the fragment sizes.
Only available if debugging is activated.
- Parameters
pkt – Network pkt.
-
NET_PKT_DATA_ACCESS_DEFINE(_name, _type)
-
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(_name, _type)
Functions
-
struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout)
Get RX DATA buffer from pool. Normally you should use net_pkt_get_frag() instead.
Normally this version is not useful for applications but is mainly used by network fragmentation code.
- Parameters
timeout – Affects the action taken should the net buf pool be empty. If K_NO_WAIT, then return immediately. If K_FOREVER, then wait as long as necessary. Otherwise, wait up to the specified time.
- Returns
Network buffer if successful, NULL otherwise.
-
struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout)
Get TX DATA buffer from pool. Normally you should use net_pkt_get_frag() instead.
Normally this version is not useful for applications but is mainly used by network fragmentation code.
- Parameters
timeout – Affects the action taken should the net buf pool be empty. If K_NO_WAIT, then return immediately. If K_FOREVER, then wait as long as necessary. Otherwise, wait up to the specified time.
- Returns
Network buffer if successful, NULL otherwise.
-
struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, k_timeout_t timeout)
Get a data fragment that might be from user specific buffer pool or from global DATA pool.
- Parameters
pkt – Network packet.
timeout – Affects the action taken should the net buf pool be empty. If K_NO_WAIT, then return immediately. If K_FOREVER, then wait as long as necessary. Otherwise, wait up to the specified time.
- Returns
Network buffer if successful, NULL otherwise.
-
void net_pkt_unref(struct net_pkt *pkt)
Place packet back into the available packets slab.
Releases the packet to other use. This needs to be called by application after it has finished with the packet.
- Parameters
pkt – Network packet to release.
-
struct net_pkt *net_pkt_ref(struct net_pkt *pkt)
Increase the packet ref count.
Mark the packet to be used still.
- Parameters
pkt – Network packet to ref.
- Returns
Network packet if successful, NULL otherwise.
-
struct net_buf *net_pkt_frag_ref(struct net_buf *frag)
Increase the packet fragment ref count.
Mark the fragment to be used still.
- Parameters
frag – Network fragment to ref.
- Returns
a pointer on the referenced Network fragment.
-
void net_pkt_frag_unref(struct net_buf *frag)
Decrease the packet fragment ref count.
- Parameters
frag – Network fragment to unref.
-
struct net_buf *net_pkt_frag_del(struct net_pkt *pkt, struct net_buf *parent, struct net_buf *frag)
Delete existing fragment from a packet.
- Parameters
pkt – Network packet from which frag belongs to.
parent – parent fragment of frag, or NULL if none.
frag – Fragment to delete.
- Returns
Pointer to the following fragment, or NULL if it had no further fragments.
-
void net_pkt_frag_add(struct net_pkt *pkt, struct net_buf *frag)
Add a fragment to a packet at the end of its fragment list.
- Parameters
pkt – pkt Network packet where to add the fragment
frag – Fragment to add
-
void net_pkt_frag_insert(struct net_pkt *pkt, struct net_buf *frag)
Insert a fragment to a packet at the beginning of its fragment list.
- Parameters
pkt – pkt Network packet where to insert the fragment
frag – Fragment to insert
-
bool net_pkt_compact(struct net_pkt *pkt)
Compact the fragment list of a packet.
After this there is no more any free space in individual fragments.
- Parameters
pkt – Network packet.
- Returns
True if compact success, False otherwise.
-
void net_pkt_get_info(struct k_mem_slab **rx, struct k_mem_slab **tx, struct net_buf_pool **rx_data, struct net_buf_pool **tx_data)
Get information about predefined RX, TX and DATA pools.
- Parameters
rx – Pointer to RX pool is returned.
tx – Pointer to TX pool is returned.
rx_data – Pointer to RX DATA pool is returned.
tx_data – Pointer to TX DATA pool is returned.
-
struct net_pkt *net_pkt_alloc(k_timeout_t timeout)
Allocate an initialized net_pkt.
for the time being, 2 pools are used. One for TX and one for RX. This allocator has to be used for TX.
- Parameters
timeout – Maximum time to wait for an allocation.
- Returns
a pointer to a newly allocated net_pkt on success, NULL otherwise.
-
struct net_pkt *net_pkt_alloc_from_slab(struct k_mem_slab *slab, k_timeout_t timeout)
Allocate an initialized net_pkt from a specific slab.
unlike net_pkt_alloc() which uses core slabs, this one will use an external slab (see NET_PKT_SLAB_DEFINE()). Do not use it unless you know what you are doing. Basically, only net_context should be using this, in order to allocate packet and then buffer on its local slab/pool (if any).
- Parameters
slab – The slab to use for allocating the packet
timeout – Maximum time to wait for an allocation.
- Returns
a pointer to a newly allocated net_pkt on success, NULL otherwise.
-
struct net_pkt *net_pkt_rx_alloc(k_timeout_t timeout)
Allocate an initialized net_pkt for RX.
for the time being, 2 pools are used. One for TX and one for RX. This allocator has to be used for RX.
- Parameters
timeout – Maximum time to wait for an allocation.
- Returns
a pointer to a newly allocated net_pkt on success, NULL otherwise.
-
struct net_pkt *net_pkt_alloc_on_iface(struct net_if *iface, k_timeout_t timeout)
Allocate a network packet for a specific network interface.
- Parameters
iface – The network interface the packet is supposed to go through.
timeout – Maximum time to wait for an allocation.
- Returns
a pointer to a newly allocated net_pkt on success, NULL otherwise.
-
struct net_pkt *net_pkt_rx_alloc_on_iface(struct net_if *iface, k_timeout_t timeout)
-
int net_pkt_alloc_buffer(struct net_pkt *pkt, size_t size, enum net_ip_protocol proto, k_timeout_t timeout)
Allocate buffer for a net_pkt.
: such allocator will take into account space necessary for headers, MTU, and existing buffer (if any). Beware that, due to all these criteria, the allocated size might be smaller/bigger than requested one.
- Parameters
pkt – The network packet requiring buffer to be allocated.
size – The size of buffer being requested.
proto – The IP protocol type (can be 0 for none).
timeout – Maximum time to wait for an allocation.
- Returns
0 on success, negative errno code otherwise.
-
struct net_pkt *net_pkt_alloc_with_buffer(struct net_if *iface, size_t size, sa_family_t family, enum net_ip_protocol proto, k_timeout_t timeout)
Allocate a network packet and buffer at once.
- Parameters
iface – The network interface the packet is supposed to go through.
size – The size of buffer.
family – The family to which the packet belongs.
proto – The IP protocol type (can be 0 for none).
timeout – Maximum time to wait for an allocation.
- Returns
a pointer to a newly allocated net_pkt on success, NULL otherwise.
-
struct net_pkt *net_pkt_rx_alloc_with_buffer(struct net_if *iface, size_t size, sa_family_t family, enum net_ip_protocol proto, k_timeout_t timeout)
-
void net_pkt_append_buffer(struct net_pkt *pkt, struct net_buf *buffer)
Append a buffer in packet.
- Parameters
pkt – Network packet where to append the buffer
buffer – Buffer to append
-
size_t net_pkt_available_buffer(struct net_pkt *pkt)
Get available buffer space from a pkt.
Note
Reserved bytes (headroom) in any of the fragments are not considered to be available.
- Parameters
pkt – The net_pkt which buffer availability should be evaluated
- Returns
the amount of buffer available
-
size_t net_pkt_available_payload_buffer(struct net_pkt *pkt, enum net_ip_protocol proto)
Get available buffer space for payload from a pkt.
Unlike net_pkt_available_buffer(), this will take into account the headers space.
Note
Reserved bytes (headroom) in any of the fragments are not considered to be available.
- Parameters
pkt – The net_pkt which payload buffer availability should be evaluated
proto – The IP protocol type (can be 0 for none).
- Returns
the amount of buffer available for payload
-
void net_pkt_trim_buffer(struct net_pkt *pkt)
Trim net_pkt buffer.
This will basically check for unused buffers and deallocate them relevantly
- Parameters
pkt – The net_pkt which buffer will be trimmed
-
int net_pkt_remove_tail(struct net_pkt *pkt, size_t length)
Remove length bytes from tail of packet.
This function does not take packet cursor into account. It is a helper to remove unneeded bytes from tail of packet (like appended CRC). It takes care of buffer deallocation if removed bytes span whole buffer(s).
- Parameters
pkt – Network packet
length – Number of bytes to be removed
- Return values
0 – On success.
-EINVAL – If packet length is shorter than length.
-
void net_pkt_cursor_init(struct net_pkt *pkt)
Initialize net_pkt cursor.
This will initialize the net_pkt cursor from its buffer.
- Parameters
pkt – The net_pkt whose cursor is going to be initialized
-
static inline void net_pkt_cursor_backup(struct net_pkt *pkt, struct net_pkt_cursor *backup)
Backup net_pkt cursor.
-
static inline void net_pkt_cursor_restore(struct net_pkt *pkt, struct net_pkt_cursor *backup)
Restore net_pkt cursor from a backup.
-
static inline void *net_pkt_cursor_get_pos(struct net_pkt *pkt)
Returns current position of the cursor.
- Parameters
pkt – The net_pkt whose cursor position is going to be returned
- Returns
cursor’s position
-
int net_pkt_skip(struct net_pkt *pkt, size_t length)
Skip some data from a net_pkt.
net_pkt’s cursor should be properly initialized Cursor position will be updated after the operation. Depending on the value of pkt->overwrite bit, this function will affect the buffer length or not. If it’s true, it will advance the cursor to the requested length. If it’s false, it will do the same but if the cursor was already also at the end of existing data, it will increment the buffer length. So in this case, its behavior is just like net_pkt_write or net_pkt_memset, difference being that it will not affect the buffer content itself (which may be just garbage then).
- Parameters
pkt – The net_pkt whose cursor will be updated to skip given amount of data from the buffer.
length – Amount of data to skip in the buffer
- Returns
0 in success, negative errno code otherwise.
-
int net_pkt_memset(struct net_pkt *pkt, int byte, size_t length)
Memset some data in a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The net_pkt whose buffer to fill starting at the current cursor position.
byte – The byte to write in memory
length – Amount of data to memset with given byte
- Returns
0 in success, negative errno code otherwise.
-
int net_pkt_copy(struct net_pkt *pkt_dst, struct net_pkt *pkt_src, size_t length)
Copy data from a packet into another one.
Both net_pkt cursors should be properly initialized and, if needed, positioned using net_pkt_skip. The cursors will be updated after the operation.
- Parameters
pkt_dst – Destination network packet.
pkt_src – Source network packet.
length – Length of data to be copied.
- Returns
0 on success, negative errno code otherwise.
-
struct net_pkt *net_pkt_clone(struct net_pkt *pkt, k_timeout_t timeout)
Clone pkt and its buffer. The cloned packet will be allocated on the same pool as the original one.
- Parameters
pkt – Original pkt to be cloned
timeout – Timeout to wait for free buffer
- Returns
NULL if error, cloned packet otherwise.
-
struct net_pkt *net_pkt_rx_clone(struct net_pkt *pkt, k_timeout_t timeout)
Clone pkt and its buffer. The cloned packet will be allocated on the RX packet poll.
- Parameters
pkt – Original pkt to be cloned
timeout – Timeout to wait for free buffer
- Returns
NULL if error, cloned packet otherwise.
-
struct net_pkt *net_pkt_shallow_clone(struct net_pkt *pkt, k_timeout_t timeout)
Clone pkt and increase the refcount of its buffer.
- Parameters
pkt – Original pkt to be shallow cloned
timeout – Timeout to wait for free packet
- Returns
NULL if error, cloned packet otherwise.
-
int net_pkt_read(struct net_pkt *pkt, void *data, size_t length)
Read some data from a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet from where to read some data
data – The destination buffer where to copy the data
length – The amount of data to copy
- Returns
0 on success, negative errno code otherwise.
-
int net_pkt_read_be16(struct net_pkt *pkt, uint16_t *data)
Read uint16_t big endian data from a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet from where to read
data – The destination uint16_t where to copy the data
- Returns
0 on success, negative errno code otherwise.
-
int net_pkt_read_le16(struct net_pkt *pkt, uint16_t *data)
Read uint16_t little endian data from a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet from where to read
data – The destination uint16_t where to copy the data
- Returns
0 on success, negative errno code otherwise.
-
int net_pkt_read_be32(struct net_pkt *pkt, uint32_t *data)
Read uint32_t big endian data from a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet from where to read
data – The destination uint32_t where to copy the data
- Returns
0 on success, negative errno code otherwise.
-
int net_pkt_write(struct net_pkt *pkt, const void *data, size_t length)
Write data into a net_pkt.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet where to write
data – Data to be written
length – Length of the data to be written
- Returns
0 on success, negative errno code otherwise.
-
size_t net_pkt_remaining_data(struct net_pkt *pkt)
Get the amount of data which can be read from current cursor position.
- Parameters
pkt – Network packet
- Returns
Amount of data which can be read from current pkt cursor
-
int net_pkt_update_length(struct net_pkt *pkt, size_t length)
Update the overall length of a packet.
Unlike net_pkt_pull() below, this does not take packet cursor into account. It’s mainly a helper dedicated for ipv4 and ipv6 input functions. It shrinks the overall length by given parameter.
- Parameters
pkt – Network packet
length – The new length of the packet
- Returns
0 on success, negative errno code otherwise.
-
int net_pkt_pull(struct net_pkt *pkt, size_t length)
Remove data from the packet at current location.
net_pkt’s cursor should be properly initialized and, eventually, properly positioned using net_pkt_skip/read/write. Note that net_pkt’s cursor is reset by this function.
- Parameters
pkt – Network packet
length – Number of bytes to be removed
- Returns
0 on success, negative errno code otherwise.
-
uint16_t net_pkt_get_current_offset(struct net_pkt *pkt)
Get the actual offset in the packet from its cursor.
- Parameters
pkt – Network packet.
- Returns
a valid offset on success, 0 otherwise as there is nothing that can be done to evaluate the offset.
-
bool net_pkt_is_contiguous(struct net_pkt *pkt, size_t size)
Check if a data size could fit contiguously.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip.
- Parameters
pkt – Network packet.
size – The size to check for contiguity
- Returns
true if that is the case, false otherwise.
-
size_t net_pkt_get_contiguous_len(struct net_pkt *pkt)
Get the contiguous buffer space
- Parameters
pkt – Network packet
- Returns
The available contiguous buffer space in bytes starting from the current cursor position. 0 in case of an error.
-
void *net_pkt_get_data(struct net_pkt *pkt, struct net_pkt_data_access *access)
Get data from a network packet in a contiguous way.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet from where to get the data.
access – A pointer to a valid net_pkt_data_access describing the data to get in a contiguous way.
- Returns
a pointer to the requested contiguous data, NULL otherwise.
-
int net_pkt_set_data(struct net_pkt *pkt, struct net_pkt_data_access *access)
Set contiguous data into a network packet.
net_pkt’s cursor should be properly initialized and, if needed, positioned using net_pkt_skip. Cursor position will be updated after the operation.
- Parameters
pkt – The network packet to where the data should be set.
access – A pointer to a valid net_pkt_data_access describing the data to set.
- Returns
0 on success, a negative errno otherwise.
-
static inline int net_pkt_acknowledge_data(struct net_pkt *pkt, struct net_pkt_data_access *access)
Acknowledge previously contiguous data taken from a network packet Packet needs to be set to overwrite mode.
-
struct net_pkt_cursor
- #include <net_pkt.h>
-
struct net_pkt
- #include <net_pkt.h>
Network packet.
Note that if you add new fields into net_pkt, remember to update net_pkt_clone() function.
Public Members
-
intptr_t fifo
The fifo is used by RX/TX threads and by socket layer. The net_pkt is queued via fifo to the processing thread.
-
struct k_mem_slab *slab
Slab pointer from where it belongs to
-
struct net_pkt_cursor cursor
Internal buffer iterator used for reading/writing
-
struct net_context *context
Network connection context
-
intptr_t fifo
-
struct net_pkt_data_access
- #include <net_pkt.h>
-
NET_PKT_SLAB_DEFINE(name, count)