A global network packet buffer. More...

Detailed Description

A global network packet buffer.

Note
WARNING!! Do not store data structures that are not packed (defined with __attribute__((packed))) or enforce alignment in in any way in here if CONFIG_GNRC_PKTBUF_SIZE > 0. On some RISC architectures this will lead to alignment problems and can potentially result in segmentation/hard faults and other unexpected behaviour.

Modules

 GNRC PKTBUF compile configurations
 
 Packet
 Network packet abstraction type and helper functions.
 

Files

file  pktbuf.h
 Interface definition for the global network buffer.
 

Functions

void gnrc_pktbuf_init (void)
 Initializes packet buffer module.
 
gnrc_pktsnip_tgnrc_pktbuf_add (gnrc_pktsnip_t *next, const void *data, size_t size, gnrc_nettype_t type)
 Adds a new gnrc_pktsnip_t and its packet to the packet buffer. More...
 
gnrc_pktsnip_tgnrc_pktbuf_mark (gnrc_pktsnip_t *pkt, size_t size, gnrc_nettype_t type)
 Marks the first size bytes in a received packet with a new packet snip that is appended to the packet. More...
 
int gnrc_pktbuf_realloc_data (gnrc_pktsnip_t *pkt, size_t size)
 Reallocates gnrc_pktsnip_t::data of pkt in the packet buffer, without changing the content. More...
 
void gnrc_pktbuf_hold (gnrc_pktsnip_t *pkt, unsigned int num)
 Increases gnrc_pktsnip_t::users of pkt atomically. More...
 
void gnrc_pktbuf_release_error (gnrc_pktsnip_t *pkt, uint32_t err)
 Decreases gnrc_pktsnip_t::users of pkt atomically and removes it if it reaches 0 and reports a possible error through an error code, if Error reporting is included. More...
 
static void gnrc_pktbuf_release (gnrc_pktsnip_t *pkt)
 Decreases gnrc_pktsnip_t::users of pkt atomically and removes it if it reaches 0 and reports GNRC_NETERR_SUCCESS. More...
 
gnrc_pktsnip_tgnrc_pktbuf_start_write (gnrc_pktsnip_t *pkt)
 Must be called once before there is a write operation on a packet snip in a thread. More...
 
gnrc_pktsnip_tgnrc_pktbuf_remove_snip (gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *snip)
 Deletes a snip from a packet and the packet buffer. More...
 
gnrc_pktsnip_tgnrc_pktbuf_replace_snip (gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *old, gnrc_pktsnip_t *add)
 Replace a snip from a packet and the packet buffer by another snip. More...
 
gnrc_pktsnip_tgnrc_pktbuf_reverse_snips (gnrc_pktsnip_t *pkt)
 Reverses snip order of a packet in a write-protected manner. More...
 
int gnrc_pktbuf_merge (gnrc_pktsnip_t *pkt)
 Merge pktsnip chain to single pktsnip. More...
 
void gnrc_pktbuf_stats (void)
 Prints some statistics about the packet buffer to stdout. More...
 
bool gnrc_pktbuf_is_empty (void)
 Checks if packet buffer is empty. More...
 
bool gnrc_pktbuf_is_sane (void)
 Checks if the implementation's internal invariants still uphold. More...
 

Function Documentation

◆ gnrc_pktbuf_add()

gnrc_pktsnip_t* gnrc_pktbuf_add ( gnrc_pktsnip_t next,
const void *  data,
size_t  size,
gnrc_nettype_t  type 
)

Adds a new gnrc_pktsnip_t and its packet to the packet buffer.

Warning
Do not change the fields of the gnrc_pktsnip_t created by this function externally. This will most likely create memory leaks or not allowed memory access.
Precondition
size < CONFIG_GNRC_PKTBUF_SIZE
Parameters
[in]nextNext gnrc_pktsnip_t in the packet. Leave NULL if you want to create a new packet.
[in]dataData of the new gnrc_pktsnip_t. If data is NULL no data will be inserted into result.
[in]sizeLength of data. If this value is 0 the gnrc_pktsnip::data field of the newly created snip will be NULL.
[in]typeProtocol type of the gnrc_pktsnip_t.
Returns
Pointer to the packet part that represents the new gnrc_pktsnip_t.
NULL, if no space is left in the packet buffer.

◆ gnrc_pktbuf_hold()

void gnrc_pktbuf_hold ( gnrc_pktsnip_t pkt,
unsigned int  num 
)

Increases gnrc_pktsnip_t::users of pkt atomically.

Parameters
[in]pktA packet.
[in]numNumber you want to increment gnrc_pktsnip_t::users of pkt by.

◆ gnrc_pktbuf_is_empty()

bool gnrc_pktbuf_is_empty ( void  )

Checks if packet buffer is empty.

Returns
true, if packet buffer is empty
false, if packet buffer is not empty

◆ gnrc_pktbuf_is_sane()

bool gnrc_pktbuf_is_sane ( void  )

Checks if the implementation's internal invariants still uphold.

Returns
true, the packet buffer is sane.
false, the packet buffer is insane.

◆ gnrc_pktbuf_mark()

gnrc_pktsnip_t* gnrc_pktbuf_mark ( gnrc_pktsnip_t pkt,
size_t  size,
gnrc_nettype_t  type 
)

Marks the first size bytes in a received packet with a new packet snip that is appended to the packet.

Graphically this can be represented as follows:

Before After
====== =====
(next)
pkt->data result->data <== pkt->data
v v v
+--------------------------------+ +----------------+---------------+
+--------------------------------+ +----------------+---------------+
\__________pkt->size___________/ \_result->size_/ \__pkt->size__/

If size == pkt->size then the resulting snip will point to NULL in its gnrc_pktsnip_t::data field and its gnrc_pktsnip_t::size field will be 0.

Precondition
pkt != NULL && size != 0
Parameters
[in]pktA received packet.
[in]sizeThe size of the new packet snip.
[in]typeThe type of the new packet snip.
Note
It's not guaranteed that result->data points to the same address as the original pkt->data.
Returns
The new packet snip in pkt on success.
NULL, if pkt == NULL or size == 0 or size > pkt->size or pkt->data == NULL.
NULL, if no space is left in the packet buffer.

◆ gnrc_pktbuf_merge()

int gnrc_pktbuf_merge ( gnrc_pktsnip_t pkt)

Merge pktsnip chain to single pktsnip.

Specifically it calls gnrc_pktbuf_realloc_data() on pkt, then copies the data of all following packet snips into that reallocated space, and removes the packet snip the data was copied from afterwards.

Example

Input

                                                    buffer
+---------------------------+                      +------+
| size = 8                  | data       +-------->|      |
| type = NETTYPE_IPV6       |------------+         +------+
+---------------------------+                      .      .
      | next                                       .      .
      v                                            .      .
+---------------------------+                      +------+
| size = 40                 | data    +----------->|      |
| type = NETTYPE_UDP        |---------+            +------+
+---------------------------+                      .      .
      | next                                       .      .
      v
+---------------------------+                      +------+
| size = 14                 | data +-------------->|      |
| type = NETTYPE_UNDEF      |------+               +------+
+---------------------------+                      .      .

Output

                                                    buffer
+---------------------------+                      +------+
| size = 62                 | data       +-------->|      |
| type = NETTYPE_IPV6       |------------+         |      |
+---------------------------+                      |      |
                                                   |      |
                                                   |      |
                                                   |      |
                                                   +------+
                                                            .      .
Warning
pkt needs to write protected before calling this function.
Note
Packets in receive order need to call gnrc_pktbuf_reverse_snips() first to get the data in the correct order.
Parameters
[in,out]pktThe snip to merge.
Returns
0, on success
ENOMEM, if no space is left in the packet buffer.

◆ gnrc_pktbuf_realloc_data()

int gnrc_pktbuf_realloc_data ( gnrc_pktsnip_t pkt,
size_t  size 
)

Reallocates gnrc_pktsnip_t::data of pkt in the packet buffer, without changing the content.

Precondition
pkt != NULL
(pkt->size > 0) <=> (pkt->data != NULL)
gnrc_pktsnip_t::data of pkt is in the packet buffer if it is not NULL.

If enough memory is available behind it or size is smaller than the original size of the packet then gnrc_pktsnip_t::data of pkt will not be moved. Otherwise, it will be moved. If no space is available nothing happens.

Parameters
[in]pktA packet part.
[in]sizeThe size for pkt.
Returns
0, on success
ENOMEM, if no space is left in the packet buffer.

◆ gnrc_pktbuf_release()

static void gnrc_pktbuf_release ( gnrc_pktsnip_t pkt)
inlinestatic

Decreases gnrc_pktsnip_t::users of pkt atomically and removes it if it reaches 0 and reports GNRC_NETERR_SUCCESS.

Parameters
[in]pktA packet.

Definition at line 178 of file pktbuf.h.

◆ gnrc_pktbuf_release_error()

void gnrc_pktbuf_release_error ( gnrc_pktsnip_t pkt,
uint32_t  err 
)

Decreases gnrc_pktsnip_t::users of pkt atomically and removes it if it reaches 0 and reports a possible error through an error code, if Error reporting is included.

Precondition
All snips of pkt must be in the packet buffer.
Parameters
[in]pktA packet.
[in]errAn error code.

◆ gnrc_pktbuf_remove_snip()

gnrc_pktsnip_t* gnrc_pktbuf_remove_snip ( gnrc_pktsnip_t pkt,
gnrc_pktsnip_t snip 
)

Deletes a snip from a packet and the packet buffer.

Parameters
[in]pktA packet.
[in]snipA snip in the packet.
Returns
The new reference to pkt.

◆ gnrc_pktbuf_replace_snip()

gnrc_pktsnip_t* gnrc_pktbuf_replace_snip ( gnrc_pktsnip_t pkt,
gnrc_pktsnip_t old,
gnrc_pktsnip_t add 
)

Replace a snip from a packet and the packet buffer by another snip.

Deprecated:
Function is not used by anyone (not even tested, see https://github.com/RIOT-OS/RIOT/issues/5089). Will be removed after 2020.10 release.
Parameters
[in]pktA packet
[in]oldsnip currently in the packet
[in]addsnip which will replace old
Returns
The new reference to pkt

◆ gnrc_pktbuf_reverse_snips()

gnrc_pktsnip_t* gnrc_pktbuf_reverse_snips ( gnrc_pktsnip_t pkt)

Reverses snip order of a packet in a write-protected manner.

This can be used to change the send/receive order of a packet (see gnrc_pktsnip_t)

Note
pkt is released on failure.
Parameters
[in]pktA packet. When this function fails (due to a full packet packet buffer) pkt will be released.
Returns
The reversed version of pkt on success
NULL, when there is not enough space in the packet buffer to reverse the packet in a write-protected manner. pkt is released in that case.

◆ gnrc_pktbuf_start_write()

gnrc_pktsnip_t* gnrc_pktbuf_start_write ( gnrc_pktsnip_t pkt)

Must be called once before there is a write operation on a packet snip in a thread.

This function duplicates a packet snip in the packet buffer (both the instance of the gnrc_pktsnip_t and its data) if gnrc_pktsnip_t::users of pkt > 1.

Parameters
[in]pktThe packet snip you want to write into.
Returns
The (new) pointer to the packet snip.
NULL, if gnrc_pktsnip_t::users of pkt > 1 and if there is not enough space in the packet buffer.

◆ gnrc_pktbuf_stats()

void gnrc_pktbuf_stats ( void  )

Prints some statistics about the packet buffer to stdout.

Note
Only available with DEVELHELP defined.

Statistics include maximum number of reserved bytes.