Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions include/zephyr/net/net_pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,13 @@ int net_pkt_alloc_buffer_debug(struct net_pkt *pkt,
net_pkt_alloc_buffer_debug(_pkt, _size, _proto, _timeout, \
__func__, __LINE__)

int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size,
k_timeout_t timeout,
const char *caller, int line);
#define net_pkt_alloc_buffer_raw(_pkt, _size, _timeout) \
net_pkt_alloc_buffer_raw_debug(_pkt, _size, _timeout, \
__func__, __LINE__)

struct net_pkt *net_pkt_alloc_with_buffer_debug(struct net_if *iface,
size_t size,
sa_family_t family,
Expand Down Expand Up @@ -1821,6 +1828,24 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt,
k_timeout_t timeout);
#endif

/**
* @brief Allocate buffer for a net_pkt, of specified size, w/o any additional
* preconditions
*
* @details: The actual buffer size may be larger than requested one if fixed
* size buffers are in use.
*
* @param pkt The network packet requiring buffer to be allocated.
* @param size The size of buffer being requested.
* @param timeout Maximum time to wait for an allocation.
*
* @return 0 on success, negative errno code otherwise.
*/
#if !defined(NET_PKT_DEBUG_ENABLED)
int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size,
k_timeout_t timeout);
#endif

/**
* @brief Allocate a network packet and buffer at once
*
Expand Down
27 changes: 16 additions & 11 deletions subsys/net/ip/net_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,7 @@ static int context_sendto(struct net_context *context,
{
const struct msghdr *msghdr = NULL;
struct net_if *iface;
struct net_pkt *pkt;
struct net_pkt *pkt = NULL;
size_t tmp_len;
int ret;

Expand Down Expand Up @@ -1935,6 +1935,15 @@ static int context_sendto(struct net_context *context,
return -ENETDOWN;
}

context->send_cb = cb;
context->user_data = user_data;

if (IS_ENABLED(CONFIG_NET_TCP) &&
net_context_get_proto(context) == IPPROTO_TCP &&
!net_if_is_ip_offloaded(net_context_get_iface(context))) {
goto skip_alloc;
}

pkt = context_alloc_pkt(context, len, PKT_WAIT_TIME);
if (!pkt) {
NET_ERR("Failed to allocate net_pkt");
Expand All @@ -1953,9 +1962,6 @@ static int context_sendto(struct net_context *context,
len = tmp_len;
}

context->send_cb = cb;
context->user_data = user_data;

if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) {
uint8_t priority;

Expand All @@ -1977,6 +1983,7 @@ static int context_sendto(struct net_context *context,
}
}

skip_alloc:
if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
net_if_is_ip_offloaded(net_context_get_iface(context))) {
ret = context_write_data(pkt, buf, len, msghdr);
Expand Down Expand Up @@ -2008,16 +2015,12 @@ static int context_sendto(struct net_context *context,
} else if (IS_ENABLED(CONFIG_NET_TCP) &&
net_context_get_proto(context) == IPPROTO_TCP) {

ret = context_write_data(pkt, buf, len, msghdr);
ret = net_tcp_queue(context, buf, len, msghdr);
if (ret < 0) {
goto fail;
}

net_pkt_cursor_init(pkt);
ret = net_tcp_queue_data(context, pkt);
if (ret < 0) {
goto fail;
}
len = ret;

ret = net_tcp_send_data(context, cb, user_data);
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
Expand Down Expand Up @@ -2073,7 +2076,9 @@ static int context_sendto(struct net_context *context,

return len;
fail:
net_pkt_unref(pkt);
if (pkt != NULL) {
net_pkt_unref(pkt);
}

return ret;
}
Expand Down
61 changes: 61 additions & 0 deletions subsys/net/ip/net_pkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,67 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt,
return 0;
}


#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size,
k_timeout_t timeout, const char *caller,
int line)
#else
int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size,
k_timeout_t timeout)
#endif
{
struct net_buf_pool *pool = NULL;
struct net_buf *buf;

if (size == 0) {
return 0;
}

if (k_is_in_isr()) {
timeout = K_NO_WAIT;
}

NET_DBG("Data allocation size %zu", size);

if (pkt->context) {
pool = get_data_pool(pkt->context);
}

if (!pool) {
pool = pkt->slab == &tx_pkts ? &tx_bufs : &rx_bufs;
}

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
buf = pkt_alloc_buffer(pool, size, timeout, caller, line);
#else
buf = pkt_alloc_buffer(pool, size, timeout);
#endif

if (!buf) {
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
NET_ERR("Data buffer (%zd) allocation failed (%s:%d)",
size, caller, line);
#else
NET_ERR("Data buffer (%zd) allocation failed.", size);
#endif
return -ENOMEM;
}

net_pkt_append_buffer(pkt, buf);

#if IS_ENABLED(CONFIG_NET_BUF_FIXED_DATA_SIZE)
/* net_buf allocators shrink the buffer size to the requested size.
* We don't want this behavior here, so restore the real size of the
* last fragment.
*/
buf = net_buf_frag_last(buf);
buf->size = CONFIG_NET_BUF_DATA_SIZE;
#endif

return 0;
}

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
static struct net_pkt *pkt_alloc(struct k_mem_slab *slab, k_timeout_t timeout,
const char *caller, int line)
Expand Down
Loading