net: pkt: Introduce minimum length requirement to net_pkt_get_frag()

net_pkt_get_frag() and a few other functions did not specify the
allocated fragment length, incorrectly assuming that fixed-sized
buffers are always used.

In order to make the function work properly also with variable-sized
buffers, extend the function argument list with minimum expected
fragment length parameter. This allows to use net_buf_alloc_len()
allocator in variable buffer length configuration, as well as verify if
the fixed-sized buffer is large enough to satisfy the requirements
otherwise.

Update the existing codebase to provide the expected fragment length,
based on the context.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2022-11-15 17:17:21 +01:00 committed by Anas Nashif
commit 387a66131e
18 changed files with 112 additions and 65 deletions

View file

@ -6,6 +6,7 @@
menuconfig ETH_SAM_GMAC
bool "Atmel SAM Ethernet driver"
default y
depends on NET_BUF_FIXED_DATA_SIZE
depends on DT_HAS_ATMEL_SAM_GMAC_ENABLED || \
DT_HAS_ATMEL_SAM0_GMAC_ENABLED
select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT

View file

@ -359,7 +359,7 @@ static void dwmac_rx_refill_thread(void *arg1, void *unused1, void *unused2)
/* get a new fragment if the previous one was consumed */
if (!frag) {
frag = net_pkt_get_reserve_rx_data(K_FOREVER);
frag = net_pkt_get_reserve_rx_data(RX_FRAG_SIZE, K_FOREVER);
if (!frag) {
LOG_ERR("net_pkt_get_reserve_rx_data() returned NULL");
k_sem_give(&p->free_rx_descs);

View file

@ -477,7 +477,8 @@ static int rx_descriptors_init(Gmac *gmac, struct gmac_queue *queue)
rx_desc_list->tail = 0U;
for (int i = 0; i < rx_desc_list->len; i++) {
rx_buf = net_pkt_get_reserve_rx_data(K_NO_WAIT);
rx_buf = net_pkt_get_reserve_rx_data(CONFIG_NET_BUF_DATA_SIZE,
K_NO_WAIT);
if (rx_buf == NULL) {
free_rx_bufs(rx_frag_list, rx_desc_list->len);
LOG_ERR("Failed to reserve data net buffers");
@ -1308,7 +1309,7 @@ static struct net_pkt *frame_get(struct gmac_queue *queue)
dcache_invalidate((uint32_t)frag_data, frag->size);
/* Get a new data net buffer from the buffer pool */
new_frag = net_pkt_get_frag(rx_frame, K_NO_WAIT);
new_frag = net_pkt_get_frag(rx_frame, CONFIG_NET_BUF_DATA_SIZE, K_NO_WAIT);
if (new_frag == NULL) {
queue->err_rx_frames_dropped++;
net_pkt_unref(rx_frame);

View file

@ -136,7 +136,7 @@ static uint8_t *upipe_rx(uint8_t *buf, size_t *off)
goto flush;
}
frag = net_pkt_get_frag(pkt, K_NO_WAIT);
frag = net_pkt_get_frag(pkt, upipe->rx_len, K_NO_WAIT);
if (!frag) {
LOG_DBG("No fragment available");
goto out;

View file

@ -68,6 +68,18 @@ struct slip_context {
#endif
};
#if defined(CONFIG_SLIP_TAP)
#define _SLIP_MTU 1500
#else
#define _SLIP_MTU 576
#endif /* CONFIG_SLIP_TAP */
#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
#define SLIP_FRAG_LEN CONFIG_NET_BUF_DATA_SIZE
#else
#define SLIP_FRAG_LEN _SLIP_MTU
#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
static inline void slip_writeb(unsigned char c)
{
uint8_t buf[1] = { c };
@ -260,7 +272,8 @@ static inline int slip_input_byte(struct slip_context *slip,
return 0;
}
slip->last = net_pkt_get_frag(slip->rx, K_NO_WAIT);
slip->last = net_pkt_get_frag(slip->rx, SLIP_FRAG_LEN,
K_NO_WAIT);
if (!slip->last) {
LOG_ERR("[%p] cannot allocate 1st data buffer",
slip);
@ -288,7 +301,7 @@ static inline int slip_input_byte(struct slip_context *slip,
/* We need to allocate a new buffer */
struct net_buf *buf;
buf = net_pkt_get_reserve_rx_data(K_NO_WAIT);
buf = net_pkt_get_reserve_rx_data(SLIP_FRAG_LEN, K_NO_WAIT);
if (!buf) {
LOG_ERR("[%p] cannot allocate next data buf", slip);
net_pkt_unref(slip->rx);
@ -454,7 +467,6 @@ static const struct ethernet_api slip_if_api = {
#define _SLIP_L2_LAYER ETHERNET_L2
#define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
#define _SLIP_MTU 1500
ETH_NET_DEVICE_INIT(slip, CONFIG_SLIP_DRV_NAME,
slip_init, NULL,
@ -471,7 +483,6 @@ static const struct dummy_api slip_if_api = {
#define _SLIP_L2_LAYER DUMMY_L2
#define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
#define _SLIP_MTU 576
NET_DEVICE_INIT(slip, CONFIG_SLIP_DRV_NAME, slip_init, NULL,
&slip_context_data, NULL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,

View file

@ -1322,30 +1322,33 @@ static inline bool net_pkt_filter_recv_ok(struct net_pkt *pkt)
*/
struct net_buf *net_pkt_get_reserve_data_debug(struct net_buf_pool *pool,
size_t min_len,
k_timeout_t timeout,
const char *caller,
int line);
#define net_pkt_get_reserve_data(pool, timeout) \
net_pkt_get_reserve_data_debug(pool, timeout, __func__, __LINE__)
#define net_pkt_get_reserve_data(pool, min_len, timeout) \
net_pkt_get_reserve_data_debug(pool, min_len, timeout, __func__, __LINE__)
struct net_buf *net_pkt_get_reserve_rx_data_debug(k_timeout_t timeout,
struct net_buf *net_pkt_get_reserve_rx_data_debug(size_t min_len,
k_timeout_t timeout,
const char *caller,
int line);
#define net_pkt_get_reserve_rx_data(timeout) \
net_pkt_get_reserve_rx_data_debug(timeout, __func__, __LINE__)
#define net_pkt_get_reserve_rx_data(min_len, timeout) \
net_pkt_get_reserve_rx_data_debug(min_len, timeout, __func__, __LINE__)
struct net_buf *net_pkt_get_reserve_tx_data_debug(k_timeout_t timeout,
struct net_buf *net_pkt_get_reserve_tx_data_debug(size_t min_len,
k_timeout_t timeout,
const char *caller,
int line);
#define net_pkt_get_reserve_tx_data(timeout) \
net_pkt_get_reserve_tx_data_debug(timeout, __func__, __LINE__)
#define net_pkt_get_reserve_tx_data(min_len, timeout) \
net_pkt_get_reserve_tx_data_debug(min_len, timeout, __func__, __LINE__)
struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt,
struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt, size_t min_len,
k_timeout_t timeout,
const char *caller, int line);
#define net_pkt_get_frag(pkt, timeout) \
net_pkt_get_frag_debug(pkt, timeout, __func__, __LINE__)
#define net_pkt_get_frag(pkt, min_len, timeout) \
net_pkt_get_frag_debug(pkt, min_len, timeout, __func__, __LINE__)
void net_pkt_unref_debug(struct net_pkt *pkt, const char *caller, int line);
#define net_pkt_unref(pkt) net_pkt_unref_debug(pkt, __func__, __LINE__)
@ -1404,6 +1407,7 @@ void net_pkt_print_frags(struct net_pkt *pkt);
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param min_len Minimum length of the requested fragment.
* @param 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.
@ -1411,7 +1415,7 @@ void net_pkt_print_frags(struct net_pkt *pkt);
* @return Network buffer if successful, NULL otherwise.
*/
#if !defined(NET_PKT_DEBUG_ENABLED)
struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout);
struct net_buf *net_pkt_get_reserve_rx_data(size_t min_len, k_timeout_t timeout);
#endif
/**
@ -1421,6 +1425,7 @@ struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout);
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param min_len Minimum length of the requested fragment.
* @param 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.
@ -1428,7 +1433,7 @@ struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout);
* @return Network buffer if successful, NULL otherwise.
*/
#if !defined(NET_PKT_DEBUG_ENABLED)
struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout);
struct net_buf *net_pkt_get_reserve_tx_data(size_t min_len, k_timeout_t timeout);
#endif
/**
@ -1436,6 +1441,7 @@ struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout);
* buffer pool or from global DATA pool.
*
* @param pkt Network packet.
* @param min_len Minimum length of the requested fragment.
* @param 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.
@ -1443,7 +1449,8 @@ struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout);
* @return Network buffer if successful, NULL otherwise.
*/
#if !defined(NET_PKT_DEBUG_ENABLED)
struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, k_timeout_t timeout);
struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, size_t min_len,
k_timeout_t timeout);
#endif
/**

View file

@ -239,7 +239,8 @@ static void dataInit(void)
tx_pkt = net_pkt_alloc(K_NO_WAIT);
__ASSERT_NO_MSG(tx_pkt != NULL);
tx_payload = net_pkt_get_reserve_tx_data(K_NO_WAIT);
tx_payload = net_pkt_get_reserve_tx_data(IEEE802154_MAX_PHY_PACKET_SIZE,
K_NO_WAIT);
__ASSERT_NO_MSG(tx_payload != NULL);
net_pkt_append_buffer(tx_pkt, tx_payload);

View file

@ -1394,16 +1394,18 @@ static bool uncompress_IPHC_header(struct net_pkt *pkt)
cursor = frag->data + diff;
memmove(cursor, frag->data, frag->len - diff);
} else {
size_t frag_len = nhc ? NET_IPV6UDPH_LEN : NET_IPV6H_LEN;
NET_DBG("Not enough tailroom. Get new fragment");
cursor = pkt->buffer->data;
frag = net_pkt_get_frag(pkt, NET_6LO_RX_PKT_TIMEOUT);
frag = net_pkt_get_frag(pkt, frag_len, NET_6LO_RX_PKT_TIMEOUT);
if (!frag) {
NET_ERR("Can't get frag for uncompression");
return false;
}
net_buf_pull(pkt->buffer, compressed_hdr_size);
net_buf_add(frag, nhc ? NET_IPV6UDPH_LEN : NET_IPV6H_LEN);
net_buf_add(frag, frag_len);
}
ipv6 = (struct net_ipv6_hdr *)(frag->data);
@ -1537,7 +1539,7 @@ static inline int compress_ipv6_header(struct net_pkt *pkt)
return 0;
}
buffer = net_pkt_get_frag(pkt, K_FOREVER);
buffer = net_pkt_get_frag(pkt, 1, K_FOREVER);
if (!buffer) {
return -ENOBUFS;
}

View file

@ -368,27 +368,32 @@ void net_pkt_print_frags(struct net_pkt *pkt)
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
struct net_buf *net_pkt_get_reserve_data_debug(struct net_buf_pool *pool,
size_t min_len,
k_timeout_t timeout,
const char *caller,
int line)
#else /* NET_LOG_LEVEL >= LOG_LEVEL_DBG */
struct net_buf *net_pkt_get_reserve_data(struct net_buf_pool *pool,
k_timeout_t timeout)
size_t min_len, k_timeout_t timeout)
#endif /* NET_LOG_LEVEL >= LOG_LEVEL_DBG */
{
struct net_buf *frag;
/*
* The reserve_head variable in the function will tell
* the size of the link layer headers if there are any.
*/
if (k_is_in_isr()) {
frag = net_buf_alloc(pool, K_NO_WAIT);
} else {
frag = net_buf_alloc(pool, timeout);
timeout = K_NO_WAIT;
}
#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
if (min_len > CONFIG_NET_BUF_DATA_SIZE) {
NET_ERR("Requested too large fragment. Increase CONFIG_NET_BUF_DATA_SIZE.");
return NULL;
}
frag = net_buf_alloc(pool, timeout);
#else
frag = net_buf_alloc_len(pool, min_len, timeout);
#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
if (!frag) {
return NULL;
}
@ -412,11 +417,11 @@ struct net_buf *net_pkt_get_reserve_data(struct net_buf_pool *pool,
* the data.
*/
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt,
struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt, size_t min_len,
k_timeout_t timeout,
const char *caller, int line)
#else
struct net_buf *net_pkt_get_frag(struct net_pkt *pkt,
struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, size_t min_len,
k_timeout_t timeout)
#endif
{
@ -427,52 +432,54 @@ struct net_buf *net_pkt_get_frag(struct net_pkt *pkt,
if (context && context->data_pool) {
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
return net_pkt_get_reserve_data_debug(context->data_pool(),
timeout, caller, line);
min_len, timeout,
caller, line);
#else
return net_pkt_get_reserve_data(context->data_pool(), timeout);
return net_pkt_get_reserve_data(context->data_pool(), min_len,
timeout);
#endif /* NET_LOG_LEVEL >= LOG_LEVEL_DBG */
}
#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */
if (pkt->slab == &rx_pkts) {
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
return net_pkt_get_reserve_rx_data_debug(timeout,
return net_pkt_get_reserve_rx_data_debug(min_len, timeout,
caller, line);
#else
return net_pkt_get_reserve_rx_data(timeout);
return net_pkt_get_reserve_rx_data(min_len, timeout);
#endif
}
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
return net_pkt_get_reserve_tx_data_debug(timeout, caller, line);
return net_pkt_get_reserve_tx_data_debug(min_len, timeout, caller, line);
#else
return net_pkt_get_reserve_tx_data(timeout);
return net_pkt_get_reserve_tx_data(min_len, timeout);
#endif
}
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
struct net_buf *net_pkt_get_reserve_rx_data_debug(k_timeout_t timeout,
struct net_buf *net_pkt_get_reserve_rx_data_debug(size_t min_len, k_timeout_t timeout,
const char *caller, int line)
{
return net_pkt_get_reserve_data_debug(&rx_bufs, timeout, caller, line);
return net_pkt_get_reserve_data_debug(&rx_bufs, min_len, timeout, caller, line);
}
struct net_buf *net_pkt_get_reserve_tx_data_debug(k_timeout_t timeout,
struct net_buf *net_pkt_get_reserve_tx_data_debug(size_t min_len, k_timeout_t timeout,
const char *caller, int line)
{
return net_pkt_get_reserve_data_debug(&tx_bufs, timeout, caller, line);
return net_pkt_get_reserve_data_debug(&tx_bufs, min_len, timeout, caller, line);
}
#else /* NET_LOG_LEVEL >= LOG_LEVEL_DBG */
struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout)
struct net_buf *net_pkt_get_reserve_rx_data(size_t min_len, k_timeout_t timeout)
{
return net_pkt_get_reserve_data(&rx_bufs, timeout);
return net_pkt_get_reserve_data(&rx_bufs, min_len, timeout);
}
struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout)
struct net_buf *net_pkt_get_reserve_tx_data(size_t min_len, k_timeout_t timeout)
{
return net_pkt_get_reserve_data(&tx_bufs, timeout);
return net_pkt_get_reserve_data(&tx_bufs, min_len, timeout);
}
#endif /* NET_LOG_LEVEL >= LOG_LEVEL_DBG */

View file

@ -92,7 +92,7 @@ static int tcp_pkt_linearize(struct net_pkt *pkt, size_t pos, size_t len)
goto out;
}
buf = net_pkt_get_frag(pkt, TCP_PKT_ALLOC_TIMEOUT);
buf = net_pkt_get_frag(pkt, len, TCP_PKT_ALLOC_TIMEOUT);
if (!buf || buf->size < len) {
if (buf) {

View file

@ -50,6 +50,12 @@ extern int net_bt_shell_init(void);
#define net_bt_shell_init(...)
#endif
#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
#define IPSP_FRAG_LEN CONFIG_NET_BUF_DATA_SIZE
#else
#define IPSP_FRAG_LEN L2CAP_IPSP_MTU
#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
struct bt_if_conn {
struct net_if *iface;
struct bt_l2cap_le_chan ipsp_chan;
@ -259,7 +265,7 @@ static struct net_buf *ipsp_alloc_buf(struct bt_l2cap_chan *chan)
{
NET_DBG("Channel %p requires buffer", chan);
return net_pkt_get_reserve_rx_data(BUF_TIMEOUT);
return net_pkt_get_reserve_rx_data(IPSP_FRAG_LEN, BUF_TIMEOUT);
}
static const struct bt_l2cap_chan_ops ipsp_ops = {

View file

@ -508,8 +508,11 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
{
struct net_buf *hdr_frag;
struct net_eth_hdr *hdr;
size_t hdr_len = IS_ENABLED(CONFIG_NET_VLAN) ?
sizeof(struct net_eth_vlan_hdr) :
sizeof(struct net_eth_hdr);
hdr_frag = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
hdr_frag = net_pkt_get_frag(pkt, hdr_len, NET_BUF_TIMEOUT);
if (!hdr_frag) {
return NULL;
}

View file

@ -460,7 +460,8 @@ int ppp_send_pkt(struct ppp_fsm *fsm, struct net_if *iface,
} else {
struct net_buf *buf;
buf = net_pkt_get_reserve_tx_data(PPP_BUF_ALLOC_TIMEOUT);
buf = net_pkt_get_reserve_tx_data(sizeof(uint16_t) + len,
PPP_BUF_ALLOC_TIMEOUT);
if (!buf) {
LOG_ERR("failed to allocate buffer");
goto out_of_mem;

View file

@ -219,6 +219,12 @@ static const char user_data[] =
"0123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789";
#if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
#define TEST_FRAG_LEN CONFIG_NET_BUF_DATA_SIZE
#else
#define TEST_FRAG_LEN 128
#endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
struct user_data_small {
char data[SIZE_OF_SMALL_DATA];
};
@ -474,7 +480,7 @@ static struct net_pkt *create_pkt(struct net_6lo_data *data)
net_pkt_lladdr_dst(pkt)->addr = dst_mac;
net_pkt_lladdr_dst(pkt)->len = 8U;
frag = net_pkt_get_frag(pkt, K_FOREVER);
frag = net_pkt_get_frag(pkt, NET_IPV6UDPH_LEN, K_FOREVER);
if (!frag) {
net_pkt_unref(pkt);
return NULL;
@ -536,7 +542,7 @@ static struct net_pkt *create_pkt(struct net_6lo_data *data)
net_pkt_frag_add(pkt, frag);
if (remaining > 0) {
frag = net_pkt_get_frag(pkt, K_FOREVER);
frag = net_pkt_get_frag(pkt, TEST_FRAG_LEN, K_FOREVER);
}
}

View file

@ -245,7 +245,7 @@ static struct net_pkt *create_pkt(struct net_fragment_data *data)
net_pkt_set_ip_hdr_len(pkt, NET_IPV6H_LEN);
buf = net_pkt_get_frag(pkt, K_FOREVER);
buf = net_pkt_get_frag(pkt, NET_IPV6UDPH_LEN, K_FOREVER);
if (!buf) {
net_pkt_unref(pkt);
return NULL;
@ -285,7 +285,7 @@ static struct net_pkt *create_pkt(struct net_fragment_data *data)
net_pkt_frag_add(pkt, buf);
if (remaining > 0) {
buf = net_pkt_get_frag(pkt, K_FOREVER);
buf = net_pkt_get_frag(pkt, CONFIG_NET_BUF_DATA_SIZE, K_FOREVER);
}
}
@ -493,7 +493,7 @@ static bool test_fragment(struct net_fragment_data *data)
while (buf) {
buf = ieee802154_6lo_fragment(&ctx, &frame_buf, data->iphc);
dfrag = net_pkt_get_frag(f_pkt, K_FOREVER);
dfrag = net_pkt_get_frag(f_pkt, frame_buf.len, K_FOREVER);
if (!dfrag) {
goto end;
}
@ -524,7 +524,7 @@ reassemble:
goto end;
}
dfrag = net_pkt_get_frag(rxpkt, K_FOREVER);
dfrag = net_pkt_get_frag(rxpkt, buf->len, K_FOREVER);
if (!dfrag) {
goto end;
}

View file

@ -48,7 +48,7 @@ static inline void insert_frag(struct net_pkt *pkt, struct net_buf *frag)
{
struct net_buf *new_frag;
new_frag = net_pkt_get_frag(pkt, K_SECONDS(1));
new_frag = net_pkt_get_frag(pkt, frag->len, K_SECONDS(1));
if (!new_frag) {
return;
}

View file

@ -464,7 +464,7 @@ static bool test_ack_reply(struct ieee802154_pkt_test *t)
NET_INFO("- Sending ACK reply to a data packet\n");
pkt = net_pkt_rx_alloc(K_FOREVER);
frag = net_pkt_get_frag(pkt, K_FOREVER);
frag = net_pkt_get_frag(pkt, sizeof(data_pkt), K_FOREVER);
memcpy(frag->data, data_pkt, sizeof(data_pkt));
frag->len = sizeof(data_pkt);

View file

@ -244,7 +244,7 @@ static void create_ack_frame(void)
const int8_t rssi = -80;
packet = net_pkt_alloc(K_NO_WAIT);
buf = net_pkt_get_reserve_tx_data(K_NO_WAIT);
buf = net_pkt_get_reserve_tx_data(ACK_PKT_LENGTH, K_NO_WAIT);
net_pkt_append_buffer(packet, buf);
buf->len = ACK_PKT_LENGTH;
@ -724,7 +724,8 @@ uint8_t alloc_pkt(struct net_pkt **out_packet, uint8_t buf_ct, uint8_t offset)
packet = net_pkt_alloc(K_NO_WAIT);
for (buf_num = 0; buf_num < buf_ct; buf_num++) {
buf = net_pkt_get_reserve_tx_data(K_NO_WAIT);
buf = net_pkt_get_reserve_tx_data(IEEE802154_MAX_PHY_PACKET_SIZE,
K_NO_WAIT);
net_pkt_append_buffer(packet, buf);
for (int i = 0; i < buf->size; i++) {