net: icmp: Add a way to send ICMP Echo-Req without waiting

Create a net_icmp_send_echo_request_no_wait() variant that will
not wait when allocating net_buf to be sent. This variant will avoid
a warning to be printed when sending Echo-Req from a system workqueue
because the work cannot sleep in this case.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2024-12-17 15:53:57 +02:00 committed by Benjamin Cabé
parent a292e89d42
commit 81c60e7257
2 changed files with 72 additions and 13 deletions

View file

@ -191,6 +191,30 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx,
struct net_icmp_ping_params *params,
void *user_data);
/**
* @brief Send ICMP echo request message without waiting during send.
*
* @details This function can be used to send ICMP Echo-Request from a system
* workqueue handler which should not have any sleeps or waits.
* This variant will do the net_buf allocations with K_NO_WAIT.
* This will avoid a warning message in the log about the timeout.
*
* @param ctx ICMP context used in this request.
* @param iface Network interface, can be set to NULL in which case the
* interface is selected according to destination address.
* @param dst IP address of the target host.
* @param params Echo-Request specific parameters. May be NULL in which case
* suitable default parameters are used.
* @param user_data User supplied opaque data passed to the handler. May be NULL.
*
* @return Return 0 if the sending succeed, <0 otherwise.
*/
int net_icmp_send_echo_request_no_wait(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct sockaddr *dst,
struct net_icmp_ping_params *params,
void *user_data);
/**
* @brief ICMP offload context structure.
*/

View file

@ -121,7 +121,8 @@ static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct in_addr *dst,
struct net_icmp_ping_params *params,
void *user_data)
void *user_data,
k_timeout_t timeout)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access,
struct net_icmpv4_echo_req);
@ -140,7 +141,7 @@ static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx,
sizeof(struct net_icmpv4_echo_req)
+ params->data_size,
AF_INET, IPPROTO_ICMP,
PKT_WAIT_TIME);
timeout);
if (!pkt) {
return -ENOMEM;
}
@ -226,12 +227,14 @@ static int send_icmpv4_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct in_addr *dst,
struct net_icmp_ping_params *params,
void *user_data)
void *user_data,
k_timeout_t timeout)
{
ARG_UNUSED(ctx);
ARG_UNUSED(iface);
ARG_UNUSED(dst);
ARG_UNUSED(params);
ARG_UNUSED(timeout);
return -ENOTSUP;
}
@ -242,7 +245,8 @@ static int send_icmpv6_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct in6_addr *dst,
struct net_icmp_ping_params *params,
void *user_data)
void *user_data,
k_timeout_t timeout)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv6_access,
struct net_icmpv6_echo_req);
@ -261,7 +265,7 @@ static int send_icmpv6_echo_request(struct net_icmp_ctx *ctx,
sizeof(struct net_icmpv6_echo_req)
+ params->data_size,
AF_INET6, IPPROTO_ICMPV6,
PKT_WAIT_TIME);
timeout);
if (!pkt) {
return -ENOMEM;
}
@ -345,12 +349,14 @@ static int send_icmpv6_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct in6_addr *dst,
struct net_icmp_ping_params *params,
void *user_data)
void *user_data,
k_timeout_t timeout)
{
ARG_UNUSED(ctx);
ARG_UNUSED(iface);
ARG_UNUSED(dst);
ARG_UNUSED(params);
ARG_UNUSED(timeout);
return -ENOTSUP;
}
@ -404,11 +410,12 @@ static int get_offloaded_ping_handler(struct net_if *iface,
return ret;
}
int net_icmp_send_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct sockaddr *dst,
struct net_icmp_ping_params *params,
void *user_data)
static int net_icmp_send_echo_request_timeout(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct sockaddr *dst,
struct net_icmp_ping_params *params,
void *user_data,
k_timeout_t timeout)
{
if (ctx == NULL || dst == NULL) {
return -EINVAL;
@ -451,7 +458,7 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx,
}
return send_icmpv4_echo_request(ctx, iface, &net_sin(dst)->sin_addr,
params, user_data);
params, user_data, timeout);
}
if (IS_ENABLED(CONFIG_NET_IPV6) && dst->sa_family == AF_INET6) {
@ -460,12 +467,40 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx,
}
return send_icmpv6_echo_request(ctx, iface, &net_sin6(dst)->sin6_addr,
params, user_data);
params, user_data, timeout);
}
return -ENOENT;
}
int net_icmp_send_echo_request(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct sockaddr *dst,
struct net_icmp_ping_params *params,
void *user_data)
{
return net_icmp_send_echo_request_timeout(ctx,
iface,
dst,
params,
user_data,
PKT_WAIT_TIME);
}
int net_icmp_send_echo_request_no_wait(struct net_icmp_ctx *ctx,
struct net_if *iface,
struct sockaddr *dst,
struct net_icmp_ping_params *params,
void *user_data)
{
return net_icmp_send_echo_request_timeout(ctx,
iface,
dst,
params,
user_data,
K_NO_WAIT);
}
static int icmp_call_handlers(struct net_pkt *pkt,
struct net_icmp_ip_hdr *ip_hdr,
struct net_icmp_hdr *icmp_hdr)